Avoid sending to block unless using O_NONBLOCK

I need to write a chat client server for a class using unix sockets (without O_NONBLOCK) and select asynchronous I / O for them. At the moment, on the server, I read 1024 bytes from the client and directly process it.

For example, in the case of a message, I get a command formatted as MSG <msg> (representing the client sending the message), I will go through all the sockets of the connected clients and write a message to them.

This approach does work, but I recently found by reading man send that it can block if the socket buffer is full and the O_NONBLOCK flag is not set on the socket.

I think this problem can occur when the client does not read for some reason (failure, listening, etc.), and this will be crucial for my server, since it will basically block until this client will not be read again.

So here is my question:

What is the correct approach to a potentially blocking socket to avoid sending a block if the socket buffer is full?

I am currently using select only to check if there is something to read on sockets, but maybe I should use it also to find out if I can write on a specific socket too? And also, can I find out how many bytes I can read / write when return is selected? For example, if you select "says" that I can write on this socket, how can I find out how many bytes I can write on the maximum before writing on this socket actually becomes a lock?

Thanks.

+4
source share
3 answers

You can use setsockopt() along with SO_SNDTIMEO to set the maximum send() , try to do your job.

See man setsockopt and man 7 socket more details.

0
source

It can be horrible. If you don't go into NONBLOCK-IN mode and call select (), which internally puts the process into sleep mode for a specific timeout value. This means that fd will be locked for this specific period of time.

0
source

This approach does work, but I recently discovered by reading the send person that it can block if the socket buffer is full and the O_NONBLOCK flag is not set on the socket.

This is why you use select, but it is still not reliable, as man select indicates:

On Linux, select () can tell the socket file descriptor to be "ready to read," but nonetheless subsequent read blocks. This can happen, for example, when the data but the exam has an incorrect checksum and is discarded. There may be other circumstances in which the file descriptor is falsely reported as ready. Thus, it can be safer to use O_NONBLOCK on sockets that should not be blocked.

0
source

All Articles