2

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

我基本上需要决定是否要将套接字发送缓冲区用作我的应用程序的唯一缓冲区,或者我是否需要自己的用户空间缓冲区来提供套接字缓冲区。

4

3 回答 3

2

它不应该,但我看不出这会如何影响您对用户空间缓冲区的决定。无论获得 EAGAIN 的具体原因如何,您是否需要缓冲区都取决于您的应用程序正在做什么。

在进行一些计算后,您还可以考虑使用带有 SO_SNDBUF 选项的setsockopt更改 tcp 缓冲区大小,以查看它是否实际上是性能上的胜利。

于 2010-06-18T15:05:13.210 回答
1

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

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

否则,我建议不要依赖这种行为,因为根据我的经验,EAGAIN 有时会在内核中出现一些小故障时返回,但套接字仍然可以。我最近在返回 EAGAIN 时体验了 HP-UX,因为显然内核内存不足。由于错误是可恢复的,因此 EAGAIN 是该案例可接受的错误代码。

于 2010-06-20T01:28:21.470 回答
1

当未确认的数据包数量达到拥塞窗口时,也可以返回 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。

于 2015-04-30T13:46:29.093 回答