TCP套接字一次可以写入多少字节?

5

正如标题所述,连接导向的套接字一次可以写入的字节数是否有限制?

如果我想发送一个缓冲区,例如1024个字节,我可以使用一个

write(tcp_socket, buffer, 1024);

我应该使用多个write()调用,每个调用发送较少的字节数吗?

可能是 https://dev59.com/12nWa4cB1Zd3GeqP3LO8#12934115 的重复。 - Leo Chapiro
5个回答

12

write()不能保证所有字节都被写入,因此需要多次调用write()。来自man write

如果出现底层物理介质空间不足,遇到RLIMIT_FSIZE资源限制(参见setrlimit(2)),或者在写入少于count个字节后被信号处理程序中断,则写入的字节数可能小于count。 (也请参阅pipe(7)。)

write()返回已写入的字节数,因此必须维护已写入字节数的运行总数,并将其用作索引进入buffer和计算剩余要写入的字节数。

ssize_t total_bytes_written = 0;
while (total_bytes_written != 1024)
{
    assert(total_bytes_written < 1024);
    ssize_t bytes_written = write(tcp_socket,
                                  &buffer[total_bytes_written],
                                  1024 - total_bytes_written);
    if (bytes_written == -1)
    {
        /* Report failure and exit. */
        break;
    }
    total_bytes_written += bytes_written;
}

所以一开始我可以使用任何“size”,然后我必须检查返回值。这样对吗? - JustTrying
1
你为什么要在那里放置 assert() 呢?怎么可能命中那个条件呢? - Mike
@Mike,这是一个循环不变式,我喜欢使用它们。在这个非常小的代码片段中可能看起来很蠢,但我觉得它们很有用。随意去掉也可以。 - hmjd

1

根据我的经验,最好保持在1024字节以下的限制。


0

没有固有的限制。TCP/IP将根据需要分段和重新组装数据包。您的系统可能会施加(可能是可调的)上限,但很可能在多MB范围内。请参阅setsockopt()的manpage,并始终检查write()的返回值。


0

您可以写入的实际数量取决于套接字类型。通常,您需要检查返回值以查看实际写入了多少字节。写入的字节数可能会因套接字是否处于阻塞模式而异。

此外,如果套接字是阻塞的,则您可能不希望一次等待所有数据都被写入。您可能希望分批写入一些数据,以便在写操作之间能够执行其他操作。


-3

正如您所看到的编写套接字,最大缓冲区大小为1048576字节。


3
请重新阅读您的资料来源。那是在IBM z/TPF上的最大套接字发送缓冲区大小,不知道是什么东西,它不是您可以在单个send()write()中发送的最大数据量,该数据量仅受指定长度的int的最大值限制。 - user207421

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接