2010-10-27 76 views
3

我试图创建一个从嵌入式控制器到Windows Vista服务器的TCP连接。我正在编写Windows服务器应用程序的一部分。Windows TCP握手问题

当控制器尝试连接时,可能需要很多次尝试来建立连接。我已经使用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分组捕获

回答

3

我看过你们的PCAP文件,我可以看到的唯一区别是:

(1)Windows客户机发送“随机寻找”在他们的SYN数据包初始序列号,而嵌入式客户端在其SYN数据包中发送初始序列号,如1,2,3。只要服务器对于(源IP,源端口,目的IP,目的端口)四元组完全没有TCP连接状态,那应该没有任何区别,但我想提及它以防万一它可以帮助你或其他人想到一个想法。(2)Windows客户端使用TCP选项发送SYN数据包,而嵌入式客户端正在发送没有TCP选项的SYN数据包。再次,据我所知,不应该导致你所看到的行为,并且可能再次为别人敲响警钟。

如果您想查看包头及其解码的更多详细信息,我推荐使用tshark作为wireshark包的一部分。您可以使用命令行像这样得到很多细节:

 
tshark -n -V -x -r Embeded-4-attempts.pcap > Embeded-4-attempts.txt 

关于“需要1次尝试连接”观察你在上面做,我会指出,这需要1周更多的时间为客户端达到Windows Vista服务器尚未见过的新的初始序列号,因为我敢打赌,每当你重新启动客户端时,它就开始发送一个序列号为1的SYN数据包,接下来是2连接尝试,然后是3等。Windows Vista服务器可能正在等待查看新的初始序列号,然后才能正确响应连接。

嗯。现在我想到了,也许问题是Vista服务器没有正确响应来自客户端的RST数据包?如果是这样,服务器认为所有这些客户端连接仍处于活动状态,而客户端没有与它们关联的状态。服务器响应ACK,以确认它仍然具有状态的连接尝试,而不是SYN-ACK,因为它仍然具有状态。客户没有他们的状态,并且表现得好像他们是新的连接一样。重新启动客户端使其重新尝试使用与上次启动时相同的TCP源端口和初始序列号,因为它的简单TCP堆栈并未像Windows客户端那样随机化这些值。

无论如何,思考的食物。如果您有权访问简单TCP客户端的源代码,请查看是否可以在创建新连接请求时使用随机源端口和初始序列号。

+0

安迪,我认为你在那里。我已经将我的服务器代码更改为在关闭“丢失”的套接字连接时更积极。现在,客户端第一次或第二次连接。它看起来像Vista缓存连接,并假定客户想重置消息编号。我正在开发客户端软件,因此经常重启嵌入式控制器,因此重置了消息编号。非常感谢您的帮助。保罗 – 2010-11-02 09:35:29

0

而握手失败,这并不遵循的协议。允许RST将连接重置为协议的一部分。问题是,为什么重置会发生?两台机器之间是否有系统发送重置信息?如果你在同一个系统上运行服务器和客户端,你还是会得到重置(这会在你的代码中出现一个错误)?如果你在不同的操作系统上运行服务器,在与Windows服务器相同的网络插座上运行,你会看到RST吗?

+0

除了非托管交换机之外,客户端和服务器之间没有任何关系。客户端是嵌入式处理器(螺旋桨芯片),因此无法在Windows下运行。 RST是允许的,但会响应不正确的应该是SYN + ACK的ACK,所以它的服务器出现故障。 – 2010-10-27 13:42:34

+0

在XP下运行服务器程序时,每次尝试时都会首次发生连接。 – 2010-10-27 13:47:32

+0

该协议允许服务器的SYN和ACK数据包分别发送或一起发送,尽管大多数实现将一起发送。你正在编写自己的TCP堆栈,还是使用嵌入式处理器的实现?你可以在模拟器中运行你的客户端吗?如果它在模拟器而不是硬件中工作,那么这将表明两者中的一个出现错误... – atk 2010-10-27 15:55:36

0

你有没有尝试从运行像Windows或Linux这样的完整操作系统的客户端使用telnet连接到Vista服务器?在Linux上,至少可以在命令行上指定要连接的TCP端口号,并查看它是否可以连接到Vista服务器。

一种可能性,以检查:是Vista的服务器上运行某种防火墙,防止发生联系?

+0

没有防火墙。我有一个非常简单的客户端程序,每次连接第一次。日志显示,对于Windows客户端,服务器使用SYN + ACK进行响应。对于嵌入式客户端,可能需要多次尝试才能获得SYN + ACK。 – 2010-10-29 09:33:42