我目前正在使用C语言从Tru64移植到Linux Suse 11.在Tru64上,他们将SO_SNDLOWAT
socket选项的值设置为1024 * 64
。在Linux上,此选项不可更改且其值为1。
我想弄清楚,没有将SO_SNDLOWAT
设置为1024 * 64
对Linux上的软件执行有什么影响。
问题是我找到了SO_SNDLOWAT
目的的两个定义(解释):
SO_SNDLOWAT
字节填充缓冲区才能继续SO_SNDLOWAT
字节空闲。我不知道该怎么做SO_SNDLOWAT
。
正如您所看到的at this question,其中包含其他套接字选项,答案取决于操作系统,因此两个答案都可能是正确的,因为一个是Linux世界的答案,一个是来自UNIX(BSD和Co)世界的答案。
在BSD和BSD克隆中,此选项表示以下内容:
send()
,它必须能够立即接受所有提供的数据或至少接受SO_SNDLOWAT
字节的数据;如果这是不可能的,它将不接受任何数据,并且send()
失败并出错。
因此,如果您将SO_SNDLOWAT
设置为100并尝试发送50个字节,它将发送50个字节或不发送任何内容。如果你将SO_SNDLOWAT
设置为100并尝试发送200个字节,它必须至少接受100个字节的数据,它可以接受更多,最多200个字节,以及100到200之间的任何值,只需不少于100个请记住,SO_SNDLOWAT
的默认值是1,这也是非阻塞套接字的默认行为(它必须接受至少1个字节或使用EWOULDBLOCK
失败)
请注意,UDP套接字总是全有或全无,它们永远不会只接受“部分数据”,因此设置SO_SNDLOWAT
仅与TCP套接字相关,它可能只接受所提供数据的一部分。SO_SNDLOWAT
对send()
调用没有实际影响,因为在这种情况下套接字将始终接受所有数据或它将阻塞然后它将阻塞直到所有数据都被接受或发送超时被命中(如果使用SO_SNDTIMEO
设置了发送超时,或者底层协议有自己的发送超时)。poll()
或select()
调用只会声称此套接字是可写的,如果SO_SNDLOWAT
调用至少可以接受send()
字节。那么这个选项真正有用的是什么?通常它用于避免您的进程在套接字缓冲区运行时以字节为单位提供数据但是在更大的块中与默认行为一样,select()
和poll()
将说套接字是可写的,即使只有单个空间套接字缓冲区中的字节。换句话说,它只是一个性能优化,因为正确使用任意套接字写入的代码将正常工作,无论是否设置SO_SNDLOWAT
,无论哪个值,如果SO_SNDLOWAT
有一个极端情况,它可能只需要更少的CPU时间合理的价值。但是,与所有性能调整一样,如果您不确切知道自己在做什么,则可能通过设置错误的值容易使事情变得更糟,因此如果有疑问,请不要触摸该设置。
第一个描述是正确的解释。
至于无法设置SO_SNDLOWAT
的影响,我认为这不重要,因为性能取决于像Nagle的算法,路径MTU发现等等。我怀疑其他TCP / IP实现默默地忽略了这个选项。
Afaik第二个是正确的,但我从来没有能够使用它。
SO_SNDLOWAT
在Linux上无法改变。setsockopt
因错误ENOPROTOOPT
而失败