读取时的套接字行为
Posted
技术标签:
【中文标题】读取时的套接字行为【英文标题】:socket behavior on read 【发布时间】:2009-11-16 17:43:30 【问题描述】:客户端每 1 秒向套接字写入 5 个字节。 服务器不断地从套接字中读取。服务器端的缓冲区长度为 10 个字节。所以函数看起来像这样
read(fd, buf, 10);
服务器每次读取 5 个字节。
现在客户端连续写入 5 个字节。 服务器是一样的。服务器每次读取 10 个字节。
套接字上的读取返回的字节数与缓冲区中可用的字节数一样多。 它不会等待填满缓冲区。
它与 SO_RCVLOWAT 有什么关系。 我读到这个套接字选项只在 select/poll io 中起作用。
谢谢
更新:
我将 SO_RCVLOWAT 更改为 10,现在它在接收缓冲区中至少等待 10 个字节。所以看起来它确实与接收缓冲区的低水位标记有关。
但我无法将低水位线设置为 0。在这种情况下,它总是将其设置为 1。为什么会这样?
【问题讨论】:
【参考方案1】:我认为 10 实际上是缓冲区的长度,因此读取将读取最多 10 个字节,但可能无法将所有内容都放入其中,或者可能无法将其填满。我相信它实际上返回写入缓冲区的字节数。
不,它通常不会等到缓冲区满才返回。
【讨论】:
【参考方案2】:如果您没有设置非阻塞 I/O,则 read() 调用将等待,直到您请求的所有字节都可用或套接字上出现错误。
如果您确实设置了非阻塞 I/O,则无法保证您甚至会获得 5 个字节 - 您可能会以 2 读取一次,以 6 读取一次 - 这取决于系统和网络时间。
【讨论】:
【参考方案3】:如果要填充 10 字节的缓冲区,可以将 SO_RCVLOWAT 设置为 10,它应该可以正常工作。
即使没有可用的SO_RCVLOWAT
字节(至少在Linux 上),poll/select 也会发出可读的套接字信号。如果您打算将套接字与 poll/select 一起使用,请注意在 poll/select 之后调用 read/recv/etc... 可能会阻塞,直到 SO_RCVLOWAT
字节数可用。
【讨论】:
以上是关于读取时的套接字行为的主要内容,如果未能解决你的问题,请参考以下文章