Reputation: 1119
I have to write a chat client-server for a class using unix sockets (without O_NONBLOCK) and select for asynchronous I/O on them. At the moment, on the server, I read 1024 bytes from the client, and directly handle it.
For example, in case of a message, I will receive a command formatted as MSG <msg>
(representing a client sending a message), I will go through all the sockets of the connected clients and write the message on them.
This approach actually works but I recently found by reading the man of send
that it can blocks if the socket buffer is full and is the flag O_NONBLOCK is not set on the socket.
I think this problem could happen when a client does not read for some reasons (crash, bugged etc.) and this would be critical for my server since it will basically blocks until this client read again.
So here is my question:
What is the correct approach on a potentially blocking socket to avoid send to block if the socket buffer is full?
I'm currently using select only to check if there is something to read on sockets but maybe I should use it also to see if I can write on a particular socket too? And also, can I know how many bytes I can read/write when select returns? For example, if select "tells" that I can write on this socket, how can I know how many bytes I can write at most before writing on this socket actually becomes blocking?
Upvotes: 3
Views: 1078
Reputation: 1723
This approach actually works but i recently found by reading the man of send that it can blocks if the socket buffer is full and is the flag O_NONBLOCK is not set on the socket.
This is why you use select, but it still isn't reliable, as man select
states:
Under Linux, select() may report a socket file descriptor as "ready for reading", while nevertheless a subsequent read blocks. This could for example happen when data has arrived but upon examination has wrong checksum and is discarded. There may be other circumstances in which a file descriptor is spuriously reported as ready. Thus it may be safer to use O_NONBLOCK on sockets that should not block.
Upvotes: 0
Reputation: 142625
It might be horrible. If you don't go NONBLOCK-ing mode and calling select(), which internally puts the process on sleep for specific timeout value. That means, fd will be blocked for that specific time period.
Upvotes: 0
Reputation: 70931
You could use setsockopt()
together with SO_SNDTIMEO
to set up a maximum amount of time send()
will try to do its work.
See man setsockopt
and man 7 socket
for details.
Upvotes: 1