【问题标题】:Maximum length of buffer in AF_UNIX socketAF_UNIX 套接字中缓冲区的最大长度
【发布时间】:2010-06-16 10:48:17
【问题描述】:

我想知道:在 C 中使用套接字 (AF_UNIX) 进行编程时,在向套接字发送或从套接字接收数据时是否有任何限制(以字节为单位)?

【问题讨论】:

    标签: c sockets


    【解决方案1】:

    您可以使用setsockoptSO_SNDBUFSO_RCVBUF)为每个单独的套接字连接更改读取和写入缓冲区。

    默认和最大尺寸取决于平台。

    此外,如果您为每个单独的读取提供更大的用户端缓冲区,例如recv

    如果您依次使用多个recvs,您可以通过连接读取无限量的字节,这将花费无限长。

    【讨论】:

    • 对于 unix 域套接字,SO_RCVBUF 对 Linux 没有影响。但 SO_SNDBUF 可用于调整发送缓冲区,但套接字发送缓冲区仍受 net.core.wmem_max 值的约束。 man7.org/linux/man-pages/man7/unix.7.html.
    【解决方案2】:

    sockets 行为是依赖于实现的。通常,当您 send() 时,无法保证将多少字节推送到套接字上。由于内核对此进行控制,因此它可以是任意数字,通常在 1500 或更少的范围内。所以你需要做的是检查 send() 返回代码并继续将数据推送到套接字上,直到你完成。此示例假定您已将套接字设置为非阻塞:

     fcntl(s, F_SETFL, O_NONBLOCK);
    
    
    int sendall(int s, char *buf, int *len)
    {
            int total = 0;        /* how many bytes we've sent */
            int bytesleft = *len; /* how many we have left to send */
            int n=0;
            int retries=0;
            struct timespec tp={0,500};
    
            while(total < *len) 
            {
                    n = send(s, buf+total, bytesleft, 0);
                    if (n == -1)
                    {
                       /* handle errors here, 
                          plus check for EWOULDBLOCK 
                          and then nanosleep()
                       */
                    }
                    total += n;
                    bytesleft -= n;
            }
    

    回答您的问题 - 不,没有限制,您不能通过一次 send() 调用发送所有数据。

    【讨论】:

    • 为什么将其设置为非阻塞,然后在紧密循环中对其进行迭代?似乎矛盾。
    • 注意 EWOULDBLOCK 注释和 timepsec 声明。这意味着在阻塞套接字上等待一小段时间。我没有展示它,你是对的,但绝对不是为了紧密循环。我删除了 40 行函数来把它放在这里。主要是因为它有一些 Solaris 特定的套接字代码。发布系统特定代码是 IMO 的坏主意,除非作为问题的一部分明确要求。
    • 嗯,你错了 a) 1500 字节 - 你假设以太网数据包大小,但它实际上是套接字 发送缓冲区,当你调用send(2),这在不同的操作系统上有所不同,但通常大于一帧(并且您在计算中忘记了 IP 和 TCP 或 UDP 标头); b) 非阻塞和 nanosleep - 您只是在模拟阻塞发送,但不会让操作系统在发送缓冲区空间可用时唤醒您。 去掉这段代码,在 Solaris 上使用/dev/poll
    猜你喜欢
    • 2010-09-06
    • 1970-01-01
    • 2010-11-09
    • 2012-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-21
    相关资源
    最近更新 更多