recently I am writing an experimental code to learn the underlying tech of TCP and UDP with epoll.
When I write the TCP code, everything works well. I send a request to a website to acquire some messages.
1. Poll event EPOLLOUT
Success to connect
New connection construct
2. Poll event EPOLLOUT
Send TCP request
3. Poll event EPOLLIN | EPOLLOUT
Call tcp message callback
The first EPOLLOUT(1) means that the connect has been finished, the second EPOLLOUT(2) means EPOLLOUT event has added to the epollfd, and the third EPOLLIN | EPOLLOUT(3) means that a message has been received and the send buffer can be used again.
But when I write the UDP code, something that I cannot understand happened.
1. Poll event EPOLLOUT
Success to connect
New connection construct
2. Poll event EPOLLOUT
Send UDP request
3. Poll event EPOLLOUT
4. Poll event EPOLLIN | EPOLLOUT
Call tcp message callback
1,2,4 is the same as 1,2,3 in TCP code, but 3 is the thing that I cannot understand. The data I sent above all are small data. Why I receive another EPOLLOUT after I send a udp request?
EPOLLOUT just means one can write. To cite from epoll_ctl: "The associated file is available for write(2) operations". Writing just puts the data into the send buffer, from where it gets eventually transmitted to the peer by the kernel. But
write(2)orsend(2)will not wait for this transmission. The send buffer is usually large enough to contain multiple messages (depending on size of message), so it is pretty normal to get EPOLLOUT again and again.EPOLLIN just means that "The associated file is available for read(2) operations". Reading is done by retrieving data from the receive buffer if possible, so EPOLLIN just means that there are data available in the receive buffer and a read will not block but return with these data.
Neither EPOLLIN nor EPOLLOUT nor any other events say anything about the message actually being received by the peer.
There is no actual epoll event for a successful connection in UDP. While in TCP there is actual communication going on for establishing a connection no such thing is done for UDP. Instead "connecting" a UDP socket will simply set the destination address on the socket without any kind of communication.