除了缓冲区已满之外,EAGAIN 会在发送时返回其他情况吗?

发布于 2024-09-06 15:30:46 字数 144 浏览 8 评论 0原文

如果我在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

吐个泡泡 2024-09-13 15:30:46

不应该,但我不明白这会如何影响您对用户空间缓冲区的决定。无论获取 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.

我要还你自由 2024-09-13 15:30:46

如果我在 Linux 中的非阻塞 tcp 套接字上使用 send(),除了发送缓冲区已满的情况之外,它还会返回 EAGAIN 吗?

在非阻塞套接字上,这应该是唯一的条件,因为 send() 仅当发送缓冲区已满时才阻塞。

否则,我建议不要依赖这种行为,因为根据我的经验,当内核中出现一些小问题时,有时会返回 EAGAIN,但套接字仍然正常。我最近在 HP-UX 上遇到了 EAGAIN 返回时的经历,因为显然内核内存不足。由于错误是可恢复的,因此 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?

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.

一身仙ぐ女味 2024-09-13 15:30:46

当未确认的数据包数量达到拥塞窗口时,也可以返回 EAGAIN/EWOULDBLOCK(对于 TCP 套接字)。

要检查套接字的拥塞窗口状态,请尝试以下操作:

#include <netinet/tcp.h>
static void print_tcp_cwnd(int socket)
{
    struct tcp_info tcp_info;
    uint tcp_info_length = sizeof(tcp_info);
    if ( getsockopt( socket, SOL_TCP, TCP_INFO, (void *)&tcp_info, &tcp_info_length ) == 0 ) 
    {
        printf("tcpi_snd_cwnd: %u, tcpi_unacked: %u\n",
            tcp_info.tcpi_snd_cwnd,
            tcp_info.tcpi_unacked
           );
    }
}

如果 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:

#include <netinet/tcp.h>
static void print_tcp_cwnd(int socket)
{
    struct tcp_info tcp_info;
    uint tcp_info_length = sizeof(tcp_info);
    if ( getsockopt( socket, SOL_TCP, TCP_INFO, (void *)&tcp_info, &tcp_info_length ) == 0 ) 
    {
        printf("tcpi_snd_cwnd: %u, tcpi_unacked: %u\n",
            tcp_info.tcpi_snd_cwnd,
            tcp_info.tcpi_unacked
           );
    }
}

If tcpi_unacked == tcpi_snd_cwnd then send() will return EAGAIN/EWOULDBLOCK for a non-blocking socket.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文