Windows上的高频数据监听器TCP过载7

我已经编码基于ac#的监听器来检索股市服务器的数据。 问题是,在通过WireShark监控之后,TCP窗口变满,这意味着接收主机(我)在处理传入数据时不够快。

我知道我的数据提供者已经禁用TCP确认,所以基本上他只是推送TCP包,看看他们是否仍然在那里:如果他发现他们没有经过一段时间的处理,连接就会closures。

我真的不知道该怎么做,我禁用了Windows 7的Auto Scale Tuning和Heuristics,但是没有任何效果。 我也注意到在Windows 7上没有办法设置TPC Windows Size(RWIN)。

我知道这不是一个编程相关的问题本身,但它是某种程度上,因为这是从代码的angular度来看是至关重要的。

编辑
一位响应者表示:“你的应用程序不能很快地将数据从数据中提取出来”,这是相当有趣的,但我并没有真正的想法来优化这个:

private class IoContext { // The socket used for the operation: public Socket _ipcSocket; // The buffer used for the operation: public VfxMsgBlock _ipcBuffer; public IoContext(Socket socket, VfxMsgBlock buffer) { _ipcSocket = socket; _ipcBuffer = buffer; } } private void InitiateRecv(IoContext rxContext) { rxContext._ipcSocket.BeginReceive(rxContext._ipcBuffer.Buffer, rxContext._ipcBuffer.WrIndex, rxContext._ipcBuffer.Remaining(), 0, CompleteRecv, rxContext); } private void CompleteRecv(IAsyncResult ar) { IoContext rxContext = ar.AsyncState as IoContext; if (rxContext != null) { int rxBytes = rxContext._ipcSocket.EndReceive(ar); if (rxBytes > 0) { //Adjust the write index in the message block: rxContext._ipcBuffer.WrIndex = rxContext._ipcBuffer.WrIndex + rxBytes; //(...) Do Stuf here with data rxContext._ipcBuffer.Crunch(); //Initiate another asynchronous read: InitiateRecv(rxContext); } } } 

编辑2
为了回应Len Holgate:

我改变/检查Recv缓冲区大小直接通过c#属性(使用GetSocketOption / SetSocketOption有一些麻烦)

我可以注意到,当我改变Socket缓冲区的大小时,会发生轻微的性能变化,也就是说,连接在10mn之后以较大的缓冲区(1000000)而不是3mn(使用10240或更less(甚至是0,我不知道为什么……奇怪) )

这是我得到的第一个WireShark日志:

 [SYN, ACK] Seq=0 Ack=1 Win=5840 Len=0 MSS=1380 SACK_PERM=1 WS=128 

它不会改变Socket的接收缓冲区大小

关于Windows 7和TCP Windows的大小,我的意思是重写Windows中的TCPpipe理,导致它自动缩放,没有registry参数可用于“手动”设置。
但是,您是对的:在每个套接字的基础上,可以使用接收缓冲区大小进行调整。
从这里来源

Solutions Collecting From Web of "Windows上的高频数据监听器TCP过载7"

如果您在TCP中禁用了确认处理,那么您就不再说TCP了。 你正在使用一些看上去有点像TCP的怪异的frankenprotocol。

通常,虽然您应该使用Windows TCP自动调整 – 这是相当不错的,虽然它取决于对等谈话TCP(在你的情况下,它不是)。

如果您需要防止窗口变满,那么最好的方法就是更快地处理数据 – 窗口填满的可能性很大,因为您的应用程序不能快速地将数据从其中拉出。 简化这应该是你的第一个停靠港。 使用异步套接字是一个很好的开始,在一行中保持多个挂起的挂起操作,这样操作系统一旦准备好就可以把数据交给你的应用程序,这将是朝正确方向迈出的又一步。

最后,如果你想使用UDP,你应该尝试使用UDP而不是Wierd TCP。

你把套接字的recv缓冲区设置得尽可能大吗?

请参阅此处了解如何影响TCP窗口大小: http : //msdn.microsoft.com/zh-cn/library/ms819736.aspx

编辑通过1GB的链接显示我得到的两台win 7机器,没有改变默认设置,只是在侦听套接字上使用setsockopt()设置SO_RECVBUF ,从连接的wireshark日志验证的窗口大小…实际的窗口尺寸是根据广告的尺寸和缩放因子暗示的乘数来计算的。

  Set Recv |Advertised |Scaling|Multiply| Actual TCP |Difference| Buf to | Window | | By |Window size | | --------+-----------+-------+--------+----------- +----------+ default | 8192 | 8 | 256 | 2097152 | | 1024 | 1024 | 0 | 1 | 1024 | 0| 10240 | 10240 | 0 | 1 | 10240 | 0| 66666666 | 65535 | 10 | 1024 | 67107840 | -441174| 666666666 | 65535 | 14 | 16384 | 1073725440 |-407058774| 1000000000 | 65535 | 14 | 16384 | 1073725440 | -73725440| 1073725440 | 65535 | 14 | 16384 | 1073725440 | 0| 1073741823 | 65535 | 14 | 16384 | 1073725440 | 16383| 1073741824 | 8192 | 8 | 256 | 2097152 |1071644672| 2147483647 | 8192 | 8 | 256 | 2097152 |2145386495| 

所以,显然,在Windows 7上可以在每个插槽的基础上影​​响TCP窗口的大小。你能否提供一个指向文档的链接,让你相信“从Windows 7开始我只是说没有TCP窗口大小可用于手动设置(只能自动调整netsh选项)“请。

请注意,recv buf设置必须应用于侦听套接字或出站套接字,然后才能发出连接,因为窗口大小缩放是在打开的握手中传输的。

在所有情况下,对setsockopt()的调用都成功了,直接调用getsockopt()会将recv缓冲区报告为之前调用setsockopt()所请求的大小。

请注意,尽管理论最大值是无符号整数2147483647的最大值,但实际最大有用值似乎为1073741823(0x3FFFFFFF),这可能随操作系统版本的不同而变化,但请记住立即调用getsockopt()除了通过查看Wireshark日志,确定1073741823以上的值被完全忽略(至少从窗口大小的角度来看),已经设置的相同的值是不可能的。

当然,这要求连接对等体指定一个窗口缩放选项,即使为0,也表示它接受窗口缩放。

请向我们展示用于初始握手包的wireshark连接日志。 我可以提供编译的代码,你可以测试这是你想要的。

作为一个补充,已经非常好的答案,我会建议下面的测试:尽可能快地提取数据,并立即丢弃。 这可以让你看到你的处理速度是否真的是问题,或者是否在其他地方。 你不能更快地阅读和扔掉数据。