Windows 什么是sou SNDBUF和sou RCVBUF

Windows 什么是sou SNDBUF和sou RCVBUF,windows,sockets,network-programming,Windows,Sockets,Network Programming,你能给我解释一下到底什么是SO_SNDBUF和SO_RCVBUF选项吗 好的,由于某些原因,操作系统会缓冲进出口数据,但我想澄清一下这个问题 他们(通常)的角色是什么 它们是每个套接字缓冲区吗 传输层的缓冲区(例如TCP缓冲区)和这些缓冲区之间是否存在连接 在使用流套接字(TCP)和无连接套接字(UDP)时,它们是否有不同的行为/角色 一篇好文章也会很棒 我在谷歌上搜索了一下,但没有找到任何有用的信息。在谷歌上搜索“SO_RECVBUF msdn”给了我 选项表中的以下几行回答了您的“它们

你能给我解释一下到底什么是
SO_SNDBUF
SO_RCVBUF
选项吗

好的,由于某些原因,操作系统会缓冲进出口数据,但我想澄清一下这个问题

  • 他们(通常)的角色是什么
  • 它们是每个套接字缓冲区吗
  • 传输层的缓冲区(例如TCP缓冲区)和这些缓冲区之间是否存在连接
  • 在使用流套接字(TCP)和无连接套接字(UDP)时,它们是否有不同的行为/角色
一篇好文章也会很棒

我在谷歌上搜索了一下,但没有找到任何有用的信息。

在谷歌上搜索“SO_RECVBUF msdn”给了我

选项表中的以下几行回答了您的“它们是每个插座的”:

SO_RCVBUF int Specifies the total per-socket buffer space reserved for receives.
SO_SNDBUF int Specifies the total per-socket buffer space reserved for sends.
稍后将详细介绍:

sou RCVBUF和sou SNDBUF

当Windows套接字实现支持SO_RCVBUF和 因此,应用程序可以请求不同的缓冲区大小 (大或小)。即使在 执行工作没有提供所要求的全部数额。一 应用程序必须使用相同的选项调用getsockopt以检查 实际提供的缓冲区大小

“SO_uuz”前缀表示“套接字选项”,因此是的,这些是每个套接字缓冲区的每个套接字设置。通常有系统范围的默认值和最大值

因此_RCVBUF
更容易理解:它是内核分配的缓冲区大小,用于在数据通过网络到达指定套接字和拥有该套接字的程序读取数据之间的时间内保存到达该套接字的数据。使用TCP,如果数据到达而您没有读取它,缓冲区将填满,发送方将被告知减速(使用TCP窗口调整机制)。对于UDP,一旦缓冲区已满,新数据包将被丢弃

我认为,只有TCP(在UDP中,您发送的任何内容都直接发送到网络)才重要。对于TCP,如果远程端没有读取数据,则可以填充缓冲区(这样远程缓冲区就满了,然后TCP将此事实传递给内核,内核停止发送数据,而是将其累积到本地缓冲区中,直到填满为止)。或者,如果出现网络问题,并且内核没有收到它发送的数据的确认,它可能会被填满。然后,它将减慢在网络上发送数据的速度,直到最终传出缓冲区填满为止。如果是这样,应用程序对该套接字的未来
write()
调用将被阻止(或者如果您设置了
O\u NONBLOCK
选项,则返回
EAGAIN


这一切在本书中得到了最好的描述。

在Windows中,发送缓冲区在UDP中确实有作用。如果发送数据包的速度快于网络传输数据包的速度,那么最终将填充套接字输出缓冲区,SendTo将以“Wild block”失败。增加SO_SNDBUF将有助于解决这一问题。我必须增加发送和接收缓冲区,以便进行一项测试,以找到在Windows设备和Linux设备之间可以发送的最大数据包速率。我还可以通过检测“将阻塞”错误代码、稍微休眠并重试来处理发送大小。但是增加发送缓冲区的大小更简单。
Windows中的默认值是8K,在这个PC机时代,8K看起来不必要的小,内存为GB

以上答案并没有回答所有问题,特别是关于套接字缓冲区和TCP缓冲区之间的关系

我认为它们是不同层次的不同事物。TCP缓冲区是套接字缓冲区的使用者

套接字缓冲区(输入和输出)是一个IO缓冲区,由系统调用从用户空间中的应用程序代码访问。 例如,使用输出缓冲区,应用程序代码可以

  • 在缓冲区已满之前立即发送数据,并在缓冲区已满时阻止
  • 设置缓冲区大小
  • 将缓冲区中的数据刷新到基础存储(TCP发送缓冲区)
  • 通过关闭流来关闭输出缓冲区
TCP缓冲区(发送和接收)位于只有操作系统才能访问的内核空间中。 例如,使用TCP发送缓冲区,TCP协议实现可以

  • 发送数据包并接受ACK
  • 保证包的交付和订购
  • 通过调整机上数据包窗口的大小来控制拥塞
顺便说一下,UDP协议没有缓冲区,但UDP套接字仍然可以有IO缓冲区

这些是我的理解,我非常高兴得到任何反馈/修改/纠正

他们(通常)的角色是什么

要通过套接字发送的数据将复制到套接字的发送缓冲区,因此代码不必等待(=块),直到数据真正发送到网络。当发送调用成功返回时,这只意味着数据已被放入发送缓冲区,协议实现将在准备通过网络发送数据时从该缓冲区读取数据

请记住,来自多个进程的多个套接字可能都希望同时发送数据,但在任何时候都只能通过网络线路发送一个数据包。在发送过程中,所有其他发送方都必须等待,一旦线路空闲,实现只能处理一个接一个的发送请求

来自网络的数据由协议实现写入套接字的接收缓冲区,在那里它将等待代码从那里读取数据。否则,所有接收都必须停止,直到您的代码处理了传入的数据包,然而,当数据包到达后台时,您的代码可能会执行其他操作,并且再次共享接口,因此,系统必须避免其他进程仅仅因为您的进程拒绝处理自己的传入数据而无法接收其网络数据

它们是per-s吗