怎样解决怎样解决W5200/W5500在在TCP通信过程中意外断开?通信过程中意外断开?
在使用W5200和W5500的TCP通信过程中,有一个非常容易被问到的问题: (这里以W5200为例) W5200作
为服务器,假如客户端的网线断开 或 瞬间停电,服务器该怎样判断? 那么当客户端由于这些原因忽然断开,该
怎样解决?
什么是Keepalive?
Keepalive即心跳检测,以下简称KA,之所以称之为心跳检测是因为它像心跳一样每隔一段时间发一次,以此来告诉对方自己
是否存活。心跳检测用于TCP通讯过程中服务器检测客户端是处于长时间空闲(在线)还是已经断开,一般采用客户端定时发
送简单的通讯包,一般是很小的包或者空包给服务器(W5200的心跳包为1字节),如果在指定时间内没有收到该心跳包,则
服务器会判断客户端已经断开,此时程序中的Socket状态机会转到SOCKET_CLOSED并重新打开Socket去连接服务器/监听
客户端。
KeepAlive怎么分类?
KA根据发出方不同可以分为两种,一种是由客户端发给服务器的心跳包,一种是服务器发给客户端的心跳包,选择哪一种方
式需要看哪一方实现起来方便合理。需要注意的是,W5200根据合理的设计,其心跳包需要在Socket TCP连接建立之后,服
务器和客户端至少进行一次数据交互,且在设定的时间内没有数据交互时发出。
W5200 KA程序说明
下面我以W5200的TCP Server官方例程为例,用PC建立TCP客户端来连接W5200,说明KA的实现方法。
定义和初始化部分:
程序中用到了定时器和中断函数,在w5200_config.c中做了定义:
void Timer_Configuration(void)
{
TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_TimeBaseStructure.TIM_Period = 1000;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_PrescalerConfig(TIM2, 71, TIM_PSCReloadMode_Immediate);
TIM_Cmd(TIM2, ENABLE);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
void Timer2_ISR(void)
{
ms++;//等待时间自增,单位为ms
if((ms % 1000)==0)//当等待时间增加到某一秒
{
if(ka_tick_flag==1)ka_no_data_tick++;//若KA定时器标志位为1,无数据传输时间计时器自增
if(ka_no_data_tick>=NO_DATA_PERIOD)
{
ka_send_tick++;//当无数据传输时间计时器值大于NO_DATA_PERIOD,KA发送定时器开始自增
if(ka_send_tick>=KA_SEND_PERIOD)