Windows TCP 握手问题
我正在尝试创建从嵌入式控制器到 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"
Try 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"
Try 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 次数据包捕获
I am trying to create a TCP connection from an embedded controller to a Windows Vista server. I am writing the Windows server part of the application.
When the controller attempts to connect, it can take many attempts to establish the connection. I have used Wireshark to debug the problem and it appears that the Windows TCP stack is not following the correct handshake protocol.
Wireshark dump:
"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"
Try 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"
Try 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 is the controller initiating the connection, 10.0.0.92 is the Windows PC.
As I understand it, the correct sequence is SYN, SYN+ACK, SYN. What I get most of the time is SYN, ACK, RST (i.e. Windows is responding with ACK rather than SYN+ACK). In the above dump it shows 3 connection attempts, the 3rd one works.
Is there anything I can do to 'fix' Windows so that it responds correctly ?
EDIT -
2 packet captures
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我查看了您的 pcap 文件,我看到的唯一区别是:
(1) Windows 客户端在其 SYN 数据包中发送“随机的”初始序列号,而嵌入式客户端发送初始序列号,如 1 、 2、 3 在它们的 SYN 数据包中。只要服务器绝对没有(源 IP、源端口、目标 IP、目标端口)4 元组的 TCP 连接状态,据我所知,这不会有任何区别,但我想提一下以防万一它可以帮助您或其他人想到一个想法。
(2) Windows 客户端发送带 TCP 选项的 SYN 数据包,而嵌入式客户端发送不带 TCP 选项的 SYN 数据包。再说一次,据我所知,这不会导致您所看到的行为,而且,也许它会给其他人敲响警钟。
如果您想查看数据包标头及其解码的更多详细信息,我推荐 tshark,它是wireshark 包的一部分。您可以使用这样的命令行获得大量详细信息:
关于您上面所做的“还需要 1 次尝试才能连接”的观察,我将指出客户端还需要 1 次时间才能达到新的初始序列号Windows Vista 服务器还没有看到,因为我敢打赌,每次重新启动客户端时,它都会首先再次发送序列号为 1 的 SYN 数据包,然后在下一次连接尝试时发送 2,然后是 3,依此类推Windows Vista 服务器可能正在等待查看新的初始序列号,然后才能正确响应连接。
唔。现在我想了一下,也许问题是Vista服务器没有正确响应来自客户端的RST数据包?如果是这样,服务器认为所有这些客户端连接仍然处于活动状态,而客户端没有与它们关联的状态。服务器用 ACK 来响应它仍然具有状态的连接尝试,而不是 SYN-ACK,因为它仍然具有它们的状态。客户端没有它们的状态,并且表现得就像它们是新连接一样。重新启动客户端会使其返回到尝试与上次启动时相同的 TCP 源端口和初始序列号,因为其简单的 TCP 堆栈不会像 Windows 客户端那样随机化这些值。
无论如何,值得深思。如果您有权访问简单 TCP 客户端的源代码,请查看是否可以使其在发出新连接请求时使用随机源端口和初始序列号。
I've looked at your pcap files, and the only differences I can see are:
(1) The Windows client is sending "random-looking" initial sequence numbers in their SYN packets, whereas the embedded client is sending initial sequence numbers like 1, 2, 3 in their SYN packets. As long as the server has absolutely no TCP connection state for the (source IP, source port, dest IP, dest port) 4-tuple, that shouldn't make any difference that I know of, but I wanted to mention it in case it helps you or someone else think of an idea.
(2) The Windows client is sending SYN packets with TCP options, whereas the embedded client is sending SYN packets with no TCP options. Again, as far as I know that should not cause the behavior you are seeing, and again, perhaps it will ring a bell for someone else.
If you want to see more details of packet headers and their decoding, I recommend tshark, which comes as part of the wireshark package. You can get lots of detail using a command line like this:
Regarding the "it takes 1 more attempt to connect" observation you make above, I will point out that it takes 1 more time for the client to reach a new initial sequence number that the Windows Vista server has not seen yet, because I'd bet that every time you reboot the client, it is starting out with sending a SYN packet with sequence number 1 again, followed by 2 on the next connection attempt, then 3, etc. The Windows Vista server may be waiting to see a new initial sequence number before it responds properly to the connection.
Hmm. Now that I think about it, perhaps the problem is the Vista server is not responding correctly to the RST packets from the client? If so, the server thinks all of these client connections are still active, while the client has no state associated with them. The server responds with ACKs to connection attempts that it still has state for, rather than SYN-ACKs, because it still has state for them. The client does not have state for them, and behaves as if they are new connections. Rebooting the client makes it go back to trying the same TCP source port and initial sequence numbers as it did last time it booted, because its simple TCP stack does not randomize these values like the Windows client probably is.
Anyway, food for thought. If you have access to source code for the simple TCP client, see if it can be made to use random source ports and initial sequence numbers when it makes new connection requests.
虽然握手失败,但这确实遵循协议。作为协议的一部分,允许 RST 重置连接。问题是,为什么会发生重置呢?两台机器之间是否有一个系统正在发送重置?如果您在同一系统上运行服务器和客户端,您是否仍然会得到重置(这表明您的代码中存在错误)?如果您在不同的操作系统上运行服务器,并且与 Windows 服务器位于同一网络插孔中,您会看到 RST 吗?
while the handshake is failing, this does follow the protocol. RST is allowed to reset the connection as part of the protocol. The question is, why is the reset ocurring? Is there a system between the two machines, whcih is sending the reset? If you run botht he server and the client on the same system, do you still get the reset (this would suggest a bug in your code)? if you run the server on a different OS, in the same network jack as the Windows server, do you see the RST?
您是否尝试过使用 telnet 从运行 Windows 或 Linux 等完整操作系统的客户端连接到 Vista 服务器?在 Linux 上,至少您可以在命令行上指定要连接的 TCP 端口号,并查看是否可以连接到您的 Vista 服务器。
一种可能的检查方法是:Vista 服务器是否运行某种阻止连接发生的防火墙?
Have you tried connecting to your Vista server from a client running a full OS like Windows or Linux, using say telnet? On Linux at least you can specify a TCP port number to connect to on the command line, and see whether that can make a connection to your Vista server or not.
One possibility to check: Is the Vista server running some kind of firewall that prevents the connection from occurring?