I wrote a small TCP servers with socket()
+ POLLIN poll()
+ recv()
+ send()
, but I don\'t know when to use <
The usual pattern is to use non-blocking file descriptors with poll()
like this:
poll()
,
POLLIN
because you are always interested in reading what the other end of the socket has send you.
POLLOUT
only if you have outstanding data to send to the other end.poll()
, if it indicates that data is available to read,
poll()
, if it indicates that the socket is writable,
POLLOUT
next time through the loopPOLLOUT
the next time through the loop.POLLOUT
the next time through the loop only if there was some data left.POLLOUT
the next time through the loop. (This choice is often easier to program because you only need to handle writing data in one place in your loop but on the other hand it delays writing the data until the next time through the loop.)From nginx source, I found that:
If there is some data to send out, nginx tries to send it with a syscall (maybe writev). However, if nginx can not send total data at one time, it will set POLLOUT on pollfd, if using poll event, to wait for a writable event. When getting a writable event, nginx will send the left data.
It is easy to reproduce this case when nginx tries to response large static file
Working on a Raspberry PI 3, Debian, using c++ 98 with gcc . . .
In an implementation of the Acceptor / Connector pattern and Reactor / Proactor / ACT pattern I regulary use POLLOUT in the following sequence:
In most cases connect returns a -1. Because of the non blocking file descriptor this is very likely. Then I check the result code.
If it is EINPROGRESS, I register an event handler in the reactor (which uses ppoll or epoll) with POLLOUT. When the connection is finally done, poll returns with POLLOUT set.
Then I create a new TcpConnection class and communicate.