我正在尝试创建从嵌入式控制器到Windows Vista服务器的TCP连接。我正在编写应用程序的Windows服务器部分。
当控制器尝试连接时,可能需要多次尝试才能建立连接。我使用Wireshark来调试问题,看起来Windows TCP堆栈没有遵循正确的握手协议。
Wireshark转储:
"No","Time","Source","Destination","Protocol","Info"
Try1:
"39","9.025322","10.0.0.252","10.0.0.92","TCP","49153 > xinuexpansion4 [SYN] Seq=0 Win=127 Len=0"
"40","9.025377","10.0.0.92","10.0.0.252","TCP","xinuexpansion4 > 49153 [ACK] Seq=1 Ack=1 Win=2048 Len=0"
"47","10.031750","10.0.0.252","10.0.0.92","TCP","49153 > xinuexpansion4 [RST] Seq=0 Win=127 Len=0"
尝试2:
"55","12.193941","10.0.0.252","10.0.0.92","TCP","49154 > xinuexpansion4 [SYN] Seq=0 Win=127 Len=0"
"56","12.194045","10.0.0.92","10.0.0.252","TCP","xinuexpansion4 > 49154 [ACK] Seq=1 Ack=1 Win=2048 Len=0"
"57","13.200431","10.0.0.252","10.0.0.92","TCP","49154 > xinuexpansion4 [RST] Seq=0 Win=127 Len=0"
尝试3:
"67","18.529871","10.0.0.252","10.0.0.92","TCP","49156 > xinuexpansion4 [SYN] Seq=0 Win=127 Len=0"
"68","18.529957","10.0.0.92","10.0.0.252","TCP","xinuexpansion4 > 49156 [SYN, ACK] Seq=0 Ack=1 Win=8192 Len=0 MSS=1460"
"69","18.536318","10.0.0.252","10.0.0.92","TCP","49156 > xinuexpansion4 [ACK] Seq=1 Ack=1 Win=127 Len=0"
10.0.0.252是启动连接的控制器,10.0.0.92是Windows PC。
据我了解,正确的序列是SYN,SYN + ACK,SYN。我大部分时间得到的是SYN,ACK,RST(即Windows响应ACK而不是SYN + ACK)。在上面的转储中,它显示了3个连接尝试,第3个连接尝试。
我能做些什么来'修复'Windows以便它能正确响应吗?
编辑 - 2个数据包捕获
答案 0 :(得分:3)
我看过你的pcap文件,我能看到的唯一区别是:
(1)Windows客户端在其SYN数据包中发送“随机查看”的初始序列号,而嵌入式客户端在其SYN数据包中发送初始序列号,如1,2,3。只要服务器完全没有(源IP,源端口,dest IP,dest端口)4元组的TCP连接状态,这不应该与我所知的有任何区别,但我想提一下以防万一它可以帮助你或其他人想出一个想法。
(2)Windows客户端正在发送带有TCP选项的SYN数据包,而嵌入式客户端正在发送没有TCP选项的SYN数据包。再说一次,据我所知,这不应该导致你所看到的行为,也许它会为别人敲响钟声。
如果您想查看数据包标头及其解码的更多细节,我建议使用tshark,它是wireshark软件包的一部分。您可以使用如下命令行获取大量详细信息:
tshark -n -V -x -r Embeded-4-attempts.pcap > Embeded-4-attempts.txt
关于上面提到的“需要再多次尝试连接”观察,我将指出客户端需要多1次时间才能达到Windows Vista服务器尚未看到的新的初始序列号,因为我敢打赌,每次重新启动客户端时,它都会再次发送序列号为1的SYN数据包,然后在下一次连接尝试时发送2,然后再发送3,等等.Windows Vista服务器可能正在等待查看一个新的初始序列号,然后才能正确响应连接。
嗯。现在我考虑一下,也许问题是Vista服务器没有正确响应来自客户端的RST数据包?如果是这样,服务器认为所有这些客户端连接仍处于活动状态,而客户端没有与之关联的状态。服务器使用ACK来响应它仍处于状态的连接尝试,而不是SYN-ACK,因为它仍然具有状态。客户端没有状态,并且表现得好像是新连接。重新启动客户端会使它返回尝试与上次启动时相同的TCP源端口和初始序列号,因为它的简单TCP堆栈不会像Windows客户端那样随机化这些值。
无论如何,值得深思。如果您可以访问简单TCP客户端的源代码,请查看在发出新连接请求时是否可以使用随机源端口和初始序列号。
答案 1 :(得分:0)
当握手失败时,这确实遵循协议。允许RST重置连接作为协议的一部分。问题是,为什么重置会发生?两台机器之间是否有系统,是否正在发送重置?如果你在同一系统上同时运行服务器和客户端,你仍然会得到重置(这会暗示你的代码中有错误)吗?如果您在不同的操作系统上运行服务器,在与Windows服务器相同的网络插孔中,您是否看到RST?
答案 2 :(得分:0)
您是否曾尝试从运行Windows或Linux等完整操作系统的客户端连接到Vista服务器,使用telnet?至少在Linux上,您可以在命令行上指定要连接的TCP端口号,并查看是否可以与Vista服务器建立连接。
检查的一种可能性:Vista服务器是否运行某种防止连接发生的防火墙?