大家是否遇到过这种问题,W5500作为server已经建立连接,突然网线掉了,然后再去连接W5500。就连不上了。
为什么?以下对这个问题进行解释说明,并提出解决的方法。
图1中的上位机程序作为client。连接W5500server。
图2是对这个问题的wireshark抓包说明。当中192.168.11.114为W5500的IP,192.168.11.110为PC的IP。下图中的第48个包是第一次握手:建立连接时,client发送SYN包到server,等待server确认;第49个包为第二次握手:server收到SYN包,必须确认客户的SYN同一时候自己也发送一个SYN包,即SYN+ACK包。第50个包为第三次握手:client收到server的SYN+ACK包,向server发送确认包ACK。此包发送完毕。client和server进入ESTABLISHED状态,完毕三次握手。
在第70个包中显示,PC向W5500发送9个字节数据。在第73个包中。W5500向PC发送9个字节数据。此时,突然拔掉网线,并点击图1 “Disconnect”button。图1中的第160个包显示的是PC发送FIN+ACK包,第161包,W5500发送应答。
然后连上网线。而且点击图3的“connect”,可是无法连接。
这是由于,网线没掉之前,W5500处于SOCK_ESTABLISHED状态。此时突然拔掉网线,SOCKET状态没变。还是SOCK_ESTABLISHED状态。没有监听,所以无法再次连接。
图1 wireshark抓包
图2 上位机建立连接
图3 网线掉了,再插上网线连接不上
解决方法:
Sn_KPALVTR寄存器配置了socket n 的keep-alive包传输时间间隔。仅仅在TCP模式下生效。单位时间为5秒。
Keep-alive包会在Sn-SR 寄存器变为SOCK_ESTABLISHED之后。且与对方至少进行过一次收或发的通信后进行传输。假设Sn_KPALVTR>0,W5500在设置的时间间隔后自己主动传输keep-alive包以检查TCP的连接状态(自己主动在线检验),假设对方不能在超时计数期内反馈keep-alive包,这个连接将会被关闭并触发超时中断。
假设‘Sn_KPALVTR = 0’。将不会启动自己主动在线验证,主机能够通过向寄存器Sn-CR写入SEND_KEEP命令发送keep-alive包(手动在线验证)。
在‘Sn_KPALVTR> 0’时,将会无视手动在线验证。
自己主动检验:仅仅需在主函数中,向寄存器Sn_KPALVTR写入不为0的数,就可以启动自己主动在线检验。
在函数中写入以下的函数,那么在W5500与对方进行过一次数据通信后,10秒后W5500自己主动发送keep-alive包。
比如:voidsetkeepalive(SOCKET s)
{
IINCHIP_WRITE(Sn_KPALVTR(s),0×02);
}
Wireshark抓包如图4
1-3包是三次握手过程,5-10包是发送和接收数据的过程。19包是W5500向PC发送keep-alive包,20包是PC对keep-alive包的应答。
10秒之后,即是第30包。W5500又发送一次keep-alive包。
此时拔掉网线,点击“Disconnect”。10秒之后。W5500发送的keep-alive包没有反应,SOCKET关闭。然后连上网线。点击“Connect”button,能够又一次建立连接,109-111包是第二次建立连接过程。
图4 启用keep-alive后能够又一次建立连接
以上演示的是自己主动发送keep-alive包的过程。假设想手动发送keep-alive包。把Sn_KPALVTR寄存器写入0。当向Sn-CR写入SEND_KEEP命令时,W5500发送一次keep-alive包。
voidsend_ka(SOCKET s)
{
IINCHIP_WRITE(Sn_CR(s),Sn_CR_SEND_KEEP);
return;
}
By Catherine
程序下载:http://wizwiki.net/forum/viewtopic.php?
f=90&t=1072
如果你有是否有任何问题,。请联系:wiznetbj@wiznet.co.kr
版权声明:本文博主原创文章。博客,未经同意不得转载。
本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/4907154.html,如需转载请自行联系原作者