读取时的套接字行为

时间:2009-11-16 17:43:30

标签: linux sockets

客户端每1秒写入5个字节到套接字。 服务器不断从套接字读取。服务器端的缓冲区长度为10个字节。所以函数看起来像这个

 read(fd, buf, 10);

服务器每次读取5个字节。

现在客户端连续写入5个字节。 服务器是一样的。服务器每次读取10个字节。

因此,套接字上的读取返回缓冲区中可用的字节数。 它不等待填满缓冲区。

是否与SO_RCVLOWAT有关。 我读到这个套接字选项只在select / poll io中有效。

感谢

更新

我将SO_RCVLOWAT更改为10,现在它至少在接收缓冲区中等待10个字节。所以看起来它确实与接收缓冲区的低水位标记有关。

但是我无法将低水印设置为0.在这种情况下,它始终将其设置为1。为什么会这样?

3 个答案:

答案 0 :(得分:2)

我认为10实际上是缓冲区的长度,因此读取最多可读取10个字节,但可能无法获取所有内容,或者可能无法填充它。我相信它实际上返回写入缓冲区的字节数。

不,它通常不会等到缓冲区满了才能返回。

答案 1 :(得分:1)

如果您尚未设置非阻塞I / O,则read()调用将等待,直到您请求的所有字节都可用或套接字上出现错误。

如果您设置了非阻塞I / O,则无法保证您甚至可以获得5个字节 - 您可能会获得一个读取2个而一个读取6个 - 这取决于系统和网络时序。

答案 2 :(得分:1)

如果要填充10字节缓冲区,可以将SO_RCVLOWAT设置为10,它应该可以正常工作。

即使没有SO_RCVLOWAT字节可用(至少在linux上),

poll / select也会将套接字发送为可读信号。如果您打算将套接字用于轮询/选择,请注意在轮询/选择之后调用read / recv / etc ...可能会阻塞,直到SO_RCVLOWAT个字节数可用。