套接字选项SO_SNDLOWAT的用途是什么

问题描述 投票:7回答:3

我目前正在使用C语言从Tru64移植到Linux Suse 11.在Tru64上,他们将SO_SNDLOWAT socket选项的值设置为1024 * 64。在Linux上,此选项不可更改且其值为1。

我想弄清楚,没有将SO_SNDLOWAT设置为1024 * 64对Linux上的软件执行有什么影响。

问题是我找到了SO_SNDLOWAT目的的两个定义(解释):

  1. 在Linux上的socket的手册页上找到: SO_SNDLOWAT 指定缓冲区中的最小字节数,直到套接字层将数据传递给协议 我知道它指定缓冲区中要进行的最小字节数(在这种情况下用于发送消息)。需要至少为SO_SNDLOWAT字节填充缓冲区才能继续
  2. 在“UNIX网络编程:W。Richard Stevens的插座网络API,Bill Fenner,Andrew M. Rudoff”一书中找到 发送低水位标记是套接字发送缓冲区中必须存在的可用空间量,以便选择返回“可写”。 我明白了,如果我想在套接字缓冲区中写入(无论我写的是什么大小),缓冲区需要至少有SO_SNDLOWAT字节空闲。

我不知道该怎么做SO_SNDLOWAT

linux sockets unix porting
3个回答
2
投票

正如您所看到的at this question,其中包含其他套接字选项,答案取决于操作系统,因此两个答案都可能是正确的,因为一个是Linux世界的答案,一个是来自UNIX(BSD和Co)世界的答案。

在BSD和BSD克隆中,此选项表示以下内容:

  1. 如果套接字是非阻塞的并且你调用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套接字相关,它可能只接受所提供数据的一部分。
  2. 如果套接字阻塞,设置SO_SNDLOWATsend()调用没有实际影响,因为在这种情况下套接字将始终接受所有数据或它将阻塞然后它将阻塞直到所有数据都被接受或发送超时被命中(如果使用SO_SNDTIMEO设置了发送超时,或者底层协议有自己的发送超时)。
  3. 无论套接字是否阻塞,无论是UDP还是TCP,poll()select()调用只会声称此套接字是可写的,如果SO_SNDLOWAT调用至少可以接受send()字节。

那么这个选项真正有用的是什么?通常它用于避免您的进程在套接字缓冲区运行时以字节为单位提供数据但是在更大的块中与默认行为一样,select()poll()将说套接字是可写的,即使只有单个空间套接字缓冲区中的字节。换句话说,它只是一个性能优化,因为正确使用任意套接字写入的代码将正常工作,无论是否设置SO_SNDLOWAT,无论哪个值,如果SO_SNDLOWAT有一个极端情况,它可能只需要更少的CPU时间合理的价值。但是,与所有性能调整一样,如果您不确切知道自己在做什么,则可能通过设置错误的值容易使事情变得更糟,因此如果有疑问,请不要触摸该设置。


1
投票

第一个描述是正确的解释。

至于无法设置SO_SNDLOWAT的影响,我认为这不重要,因为性能取决于像Nagle的算法,路径MTU发现等等。我怀疑其他TCP / IP实现默默地忽略了这个选项。


1
投票

Afaik第二个是正确的,但我从来没有能够使用它。

SO_SNDLOWAT在Linux上无法改变。 setsockopt因错误ENOPROTOOPT而失败

© www.soinside.com 2019 - 2024. All rights reserved.