问题
I am using SOCK_SEQPACKET connection, and it is critical for me to ensure that whole buffer is sent with single write()/send() call. I am also operating with device driver that is designed to handle a complete block of data with single call. At the same time I want to handle the situation when write()/send() blocks due to buffer overflow, i.e. I want to have a feedback whether current implementation gets a bottleneck here. I'm working with glibc, Linux 2.6.
I need to implement a method that accepts a buffer, and it either sends a buffer completely or indicates a failure due to blocking (i.e. system buffer overflow).
It looks like using send(..., MSG_DONTWAIT)/fcntl(..., O_NONBLOCK) is not a solution as they accept partial write prior to reporting EWOULDBLOCK/EAGAIN. Is there a way to check whether there is enough space in outgoing buffer or is there a dedicated write-complete-or-fail method?
Alternatively, is it possible to detect block by other means? For example, timer+signal seems to be an option, but I do not like the idea to set it for each write.
Thank you in advance.
回答1:
Experiment reveals that no partial send occurs on my setup (glibc 2.11.1, kernel 2.6.32-29) and that EAGAIN/EWOULDBLOCK is returned by send(...MSG_DONTWAIT) as expected for AF_UNIX+SOL_SEQPACKET socket.
Not sure whether behavior is universal.
回答2:
Reading the value of SO_SNDLOWAT on the socket will give you a clue as to the sizes of messages that can be sent without risking partial sends.
来源:https://stackoverflow.com/questions/6788152/check-that-write-send-can-process-whole-buffer-without-block-fail-otherwise