除了缓冲区已满之外,EAGAIN是否会返回发送?

时间:2010-06-18 13:45:36

标签: linux networking tcp sockets send

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

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

3 个答案:

答案 0 :(得分:2)

它不应该,但我不知道这会如何影响您对用户空间缓冲区的决定。根据您的应用正在做什么,您可能需要缓冲区,无论获取EAGAIN的具体原因如何。

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

答案 1 :(得分:1)

  

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

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

否则,我建议不要依赖于我的经验中的行为EAGAIN有时会在内核中出现次要故障时返回,但socket仍然可以。我最近在返回EAGAIN时遇到了HP-UX的经验,因为显然内核内存不足。由于错误是可以恢复的,因此EAGAIN是可接受的案例错误代码。

答案 2 :(得分:1)

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

检查插座w.r.t的状态。拥塞窗口,然后试试这个:

#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以获取非阻塞套接字。