linux write():它是否尝试写入尽可能多的字节?
如果我以这种方式使用linux write():它是否尝试写入尽可能多的字节?,linux,network-programming,Linux,Network Programming,如果我以这种方式使用write:write(fd,buf,10000000/*10MB*/)其中fd是一个套接字并使用阻塞I/O,内核是否会尝试刷新尽可能多的字节,以便只需一次调用就足够了?或者我必须根据其返回值调用write多次?如果发生这种情况,是否意味着fd有问题 ===========================================编辑================================ 谢谢你的回答。此外,如果我将fd放入poll中,并使用POLLOUT成功
write
:write(fd,buf,10000000/*10MB*/)
其中fd
是一个套接字并使用阻塞I/O,内核是否会尝试刷新尽可能多的字节,以便只需一次调用就足够了?或者我必须根据其返回值调用write
多次?如果发生这种情况,是否意味着fd有问题
===========================================编辑================================
谢谢你的回答。此外,如果我将fd
放入poll
中,并使用POLLOUT
成功返回,则无法阻止对write
的调用并写入所有数据,除非在阻塞模式下fd
出现问题?仅在写入指定字节数时才会返回。如果它不能写,它会等待
在非阻塞(O_NONBLOCK
)模式下,它不会等待。它马上就回来。如果它能写下所有这些,它将是一个成功,否则它将相应地设置错误。然后您必须检查errno
,如果它的ewoodblock
或EAGAIN
必须调用相同的write
agian
摘自
例如,如果基础物理介质或RLIMIT_FSIZE资源上的空间不足,则写入的字节数可能小于count
遇到限制(请参阅setrlimit(2)),或者在写入少于count字节后,调用被信号处理程序中断。(另见管道(7))
所以是的,fd
可能有问题
还要注意这一点
从write()成功返回并不保证数据已提交到磁盘。事实上,在一些有缺陷的实现上,它甚至没有
确保已成功为数据保留空间。确保的唯一方法是在完成所有数据的写入后调用fsync(2)
/etc/sysctl.conf在Linux中用于设置TCP协议的参数,我想您所说的套接字就是这个意思。这里可能有很多参数,但当您仔细研究时,基本上TCP缓冲区一次可以保存的数据量是有限的 因此,如果您尝试一次性写入10 MB数据,write将返回一个与该值相等的
ssize\t
值。始终检查write()系统调用的返回值。如果系统允许10MB,则write将返回该值
价值是
net.core.wmem_max = [some number]
如果您将某个数字更改为一个足够大的值,以允许10MB的容量,您就可以写入这么多。不要那样做!你可能会引起其他问题。在做任何事情之前先研究一下设置。更改设置会降低性能。小心点
http://linux.die.net/man/7/tcp
具有TCP设置的基本C信息。还可以在您的对话框中查看/proc/sys/net
另一点——TCP是一个双向门,因此,一次可以发送无数字节并不意味着另一方可以读取甚至处理它。您的插座可能会阻塞一段时间。您的write()返回值可能比您希望的要小。
10000000/*10MB*/
-不,实际上是9.54 MB。write()可以返回它想要的任何内容(介于-1和N之间,两者都包括在内,N是第三个参数)@Duck您在谈论空间限制和fsync问题吗?只有在出现错误或向进程发送信号时,Write才会返回发送的数据不完整,在这种情况下,errno==EINTR
。后者非常罕见,除非在代码中使用计时器或类似的东西。但请记住,fd
在呼叫开始时可能是“正确的”,但如果另一端关闭套接字,则您的fd
不再连接,因此您将得到不完整的写入和EPIPE
或类似错误。此答案不正确。非阻塞仅意味着write()将阻塞,直到写入内容或发生错误。OP需要为不完整的写入编写代码。@实际上,fizzer会阻止所有实现,直到所有数据都已缓冲(如果未发送)。关于这一点,新闻上有一个长长的帖子:comp.protocols.tcp-ip,一年或两年前,所有实现者都住在那里。有趣。我在Linux上进行了尝试,您似乎是正确的(例外:当发送方收到信号时,我看到了部分写入)。我在谷歌群组上找不到这个帖子。如果你再找到它,请把它寄出去。