除了缓冲区已满之外,EAGAIN 会在发送时返回其他情况吗?
如果我在 Linux 中的非阻塞 tcp 套接字上使用 send(),除了发送缓冲区已满的情况之外,它还会返回 EAGAIN 吗?
我基本上需要决定是否要使用套接字发送缓冲区作为我的应用程序的唯一缓冲区,或者我是否需要自己的用户空间缓冲区来提供套接字缓冲区。
If I use send() on a non-blocking tcp socket in Linux will it return EAGAIN for anything other than a send buffer full condition?
I basically need to decide if I want to use the socket send buffer as the only buffer for my app or if I need my own user space buffer to feed the socket buffer.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
不应该,但我不明白这会如何影响您对用户空间缓冲区的决定。无论获取 EAGAIN 的具体原因是什么,您是否需要缓冲区都取决于您的应用程序正在执行的操作。
您还可以考虑在执行后使用 SO_SNDBUF 选项使用 setsockopt 更改 tcp 缓冲区大小进行一些计算,看看它是否确实是性能上的胜利。
It shouldn't but I don't see how that affects your decision about a user space buffer one way or another. Either you'll need a buffer or not depending on what your app is doing, regardless of the specific reason for getting an EAGAIN.
You can also think about changing the tcp buffer size with setsockopt with the SO_SNDBUF option after doing some calculations to see if it is actually a performance win or not.
在非阻塞套接字上,这应该是唯一的条件,因为 send() 仅当发送缓冲区已满时才阻塞。
否则,我建议不要依赖这种行为,因为根据我的经验,当内核中出现一些小问题时,有时会返回 EAGAIN,但套接字仍然正常。我最近在 HP-UX 上遇到了 EAGAIN 返回时的经历,因为显然内核内存不足。由于错误是可恢复的,因此 EAGAIN 对于这种情况来说是可接受的错误代码。
On non-blocking socket that should be only condition, as send() blocks only when the send buffer is full.
Otherwise, I would suggest not to depend on the behavior as in my experience EAGAIN sometimes returned when something minor fails in kernel, yet socket is still OK. I had recently the experience on HP-UX when EAGAIN was returned since apparently kernel was running low on memory. As error is recoverable, EAGAIN is acceptable error code for the case.
当未确认的数据包数量达到拥塞窗口时,也可以返回 EAGAIN/EWOULDBLOCK(对于 TCP 套接字)。
要检查套接字的拥塞窗口状态,请尝试以下操作:
如果 tcpi_unacked == tcpi_snd_cwnd 则 send() 将为非阻塞套接字返回 EAGAIN/EWOULDBLOCK。
EAGAIN/EWOULDBLOCK can also be returned (for TCP sockets) when the number of unacknowledged packets has reached the congestion window.
To check the status of the socket w.r.t. the congestion window, then try this:
If
tcpi_unacked == tcpi_snd_cwnd
then send() will return EAGAIN/EWOULDBLOCK for a non-blocking socket.