Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 插座选项的用途是什么_Linux_Sockets_Unix_Porting - Fatal编程技术网

Linux 插座选项的用途是什么

Linux 插座选项的用途是什么,linux,sockets,unix,porting,Linux,Sockets,Unix,Porting,我目前正在用C语言将一个软件从Tru64移植到Linux Suse 11。 在Tru64上,他们将SO_SNDLOWAT套接字选项的值设置为1024*64。在Linux上,此选项不可更改,其值为1 我想弄清楚,不将SO_SNDLOWAT设置为1024*64会对Linux上的软件执行产生什么影响 问题是,我发现了两种关于SO_SNDLOWAT目的的定义和解释: 在Linux上socket的手册页上找到: 苏斯诺瓦特 指定缓冲区中的最小字节数,直到 套接字层将数据传递给协议 我知道它指定了在这种情况

我目前正在用C语言将一个软件从Tru64移植到Linux Suse 11。 在Tru64上,他们将SO_SNDLOWAT套接字选项的值设置为1024*64。在Linux上,此选项不可更改,其值为1

我想弄清楚,不将SO_SNDLOWAT设置为1024*64会对Linux上的软件执行产生什么影响

问题是,我发现了两种关于SO_SNDLOWAT目的的定义和解释:

在Linux上socket的手册页上找到:

苏斯诺瓦特 指定缓冲区中的最小字节数,直到 套接字层将数据传递给协议

我知道它指定了在这种情况下发送消息所需的缓冲区中的最小字节数。至少需要填充缓冲区才能继续执行SO_SNDLOWAT字节

可以在《UNIX网络编程:W.Richard Stevens、Bill Fenner、Andrew M.Rudoff的套接字网络API》一书中找到

send low water mark是套接字发送缓冲区中必须存在的可用空间量,以便select返回可写

我明白,如果我想在套接字缓冲区中写入内容,不管我正在写入的内容大小,缓冲区至少需要有大约个字节的空闲空间


我不知道如何理解苏斯诺瓦特。

第一个描述是正确的解释


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

Afaik第二个选项是正确的,但我从未使用过它

因此,在Linux上,SNDLOWAT是不可更改的。setsockopt在以下情况下失败: Protoop错误

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

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

如果套接字是非阻塞的,并且您调用send,那么它必须能够一次接受所有提供的数据,或者至少接受大约字节的数据;如果这是不可能的,它将不接受任何数据,并且发送失败并出现错误

因此,如果您将So_SNDLOWAT设置为100并尝试发送50个字节,它将发送50个字节或什么也不发送。如果您将SO_SNDLOWAT设置为100并尝试发送200字节,则它必须至少接受100字节的数据,它可以接受更多的数据,最多可以接受整个200字节,以及100到200之间的任何值,但不能小于100。请记住,SO_SNDLOWAT的默认值为1,这也是非阻塞套接字的默认行为,它必须接受至少1字节,否则将使用eWoldBlock失败

请注意,UDP套接字总是全部或全无,它们从不只接受部分数据,因此设置为仅与TCP套接字相关,TCP套接字可能只接受提供的部分数据

如果套接字阻塞,那么设置SO_SNDLOWAT对发送调用没有实际影响,在这种情况下,套接字将始终接受所有数据,或者它将阻塞,然后它将阻塞,直到所有数据都被接受,或者如果发送超时已使用SO_SNDTIMEO设置,或者基础协议有自己的发送超时,则会命中发送超时

无论套接字是否阻塞,无论它是UDP还是TCP,轮询或选择调用都只会声明此套接字是可写的,前提是发送调用至少可以接受SO_SNDLOWAT字节


那么,这个选项真正有什么好处呢?通常,它用于避免进程在套接字缓冲区满后以逐字节的方式提供数据,但在较大的块中,与默认行为一样,select和poll会说套接字是可写的,即使套接字缓冲区中只有一个字节的空间。换句话说,这只是一种性能优化,因为无论是否设置了SO_SNDLOWAT,以及设置了哪个值,在某些极端情况下,如果SO_SNDLOWAT有一个合理的值,能够正确处理任意套接字写入的代码都能正常工作,可能只需要更少的CPU时间。但与所有性能调整一样,如果您不知道自己在做什么,设置错误的值很容易让事情变得更糟,因此如果有疑问,请不要触摸该设置。

在链表情况下,使用第二个功能也有意义:如果select询问套接字是否可写,此时内核应该分配一个缓冲区,并且只有在可能的情况下才返回到应用程序。我可以看出要求保证send至少可以接受n个字节的好处。它们是。TCP\u NOTSENT\u LOWAT已经在内核2.12中引入了。@Matt你把TCP\u NOTSENT\u LOWAT误认为是SO\u SNDLOWAT