不, GetResponseStream返回的 Stream 对象没有缓冲。
您的第二部分(关于设置断点)的简短回答是您的同事不正确。网络流量将停止,但最终,并描述“最终”,请继续阅读以了解更多详细信息。
Bing用于“SO_RCVBUF”、“tcp 接收窗口大小”、“vista 自动缩放”,以获得更多一般信息。
详细部分
让我们从这个开始,这是 Windows 网络堆栈的文本视图:
++ .NET 网络 API
++ --- Winsock DLL(用户模式)
++ ------ afd.sys(内核模式)
++ --------- tcpip.sys
++ ------------ ndis
++ --------------- 网络接口(hal)
这是一个粗略的堆栈,掩盖了一些细节,但总体思路是 .NET 调用 Winsock 用户模式 dll,然后将大部分实际工作推送到其表亲AFD(辅助功能驱动程序),然后推送到 tcpip 子系统等等..
在AFD级别,有一个缓冲区,通常在8K 和 64K之间,但对于 Vista(及更高版本),它也可以扩展。此设置也可以通过注册表设置 ( HKLM\SYSTEM\CurrentControlSet\services\AFD\Parameters ) 控制。
此外,tcpip.sys 也有一个缓冲区,类似于 AFD 的缓冲区。我相信打开套接字时传递的 *SO_RCVBUF* 设置也可以改变这一点。
本质上,当您接收数据时,代表您的tcpip.sys会继续获取数据,并一直告诉发送者它已获取数据( ACK),并一直这样做直到其缓冲区已满。但与此同时,afd.sys通过向 tcpip.sys 请求数据(然后将其复制到自己的缓冲区中)来清除tcpip.sys缓冲区,因此tcpip.sys可以填充来自发送方的更多数据。
然后是你(.NET API 调用者),他也在做同样的事情,调用 Read() 方法并将数据复制到缓冲区中。
因此,如果您考虑一下,一条 256Kb 的消息通过网络传输,64K 位于tcpip.sys缓冲区中,64K 位于afd.sys缓冲区中,并且您在请求一个 4K(您的 bufferSize 变量)块后设置了一个断点,我们正在查看收到的 128K ACK'ed 返回给发送者,并且由于tcpip.sys缓冲区现在已满(假设为 64K 大小)(并且您被调试会话阻止),tcpip.sys将没有选项但是告诉发送者停止通过网络发送字节,因为它不能足够快地处理它们。
实际上(即有人没有设置断点!),我已经看到 GC 会引发这种行为。看到一个 3 秒垃圾收集的案例,它让所有操作系统缓冲区填满。