检查 write()/send() 是否可以无阻塞地处理整个缓冲区,否则失败(无部分写入)
我正在使用 SOCK_SEQPACKET 连接,确保通过单个 write()/send() 调用发送整个缓冲区对我来说至关重要。我还使用设备驱动程序进行操作,该驱动程序旨在通过单个调用处理完整的数据块。同时我想处理 write()/send() 由于缓冲区溢出而阻塞的情况,即我想获得当前实现是否遇到瓶颈的反馈。我正在使用 glibc,Linux 2.6。
我需要实现一个接受缓冲区的方法,它要么完全发送缓冲区,要么指示由于阻塞而失败(即系统缓冲区溢出)。
看起来使用 send(..., MSG_DONTWAIT)/fcntl(..., O_NONBLOCK) 不是一个解决方案,因为它们在报告 EWOULDBLOCK/EAGAIN 之前接受部分写入。有没有办法检查传出缓冲区是否有足够的空间,或者是否有专用的写入完成或失败方法?
或者,是否可以通过其他方式检测阻塞?例如,计时器+信号似乎是一个选项,但我不喜欢为每次写入设置它的想法。
先感谢您。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
实验表明,我的设置(glibc 2.11.1,内核 2.6.32-29)上没有发生部分发送,并且 send(...MSG_DONTWAIT) 返回了 EAGAIN/EWOULDBLOCK,正如 AF_UNIX+SOL_SEQPACKET 套接字所预期的那样。
不确定行为是否具有普遍性。
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.
读取套接字上 SO_SNDLOWAT 的值将为您提供有关可以发送的消息大小的线索,而不会带来部分发送的风险。
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.