原子探索者 F407 LWIP 客户端多连接 断网线断服务 重新连接
通过链路检测判断链路是否正常,并在正常后重新连接
通过子任务来启动连接,几个连接,就几个子任务
1、链路检测
通过判断gnetif标志位,判断链路是否正常:
gnetif为系统定义的网卡接口结构体
while(netif_is_link_up(&gnetif) ==0 )
如果没有连上网线,则不启动连接子任务
2、客户端启动任务
需要启动一个定时器,周期性的工作在这里执行。
如果链路中断,程序会将发送数据送入缓存。在连接正常后,通过定时器将数据发送出去。
void startTcpClient(void)
{
uint8_t i;
osDelay(500);
//连接数据库初始化
clientInit();
//如果网线没有插上,则不启动连接子任务,不做数据发送
while(netif_is_link_up(&gnetif) ==0 )
osDelay(100);
clientTimer = xTimerCreate("client task timer",1000,pdTRUE,0,clientTimerCallback);
if(clientTimer!=NULL )
{
xTimerStart( clientTimer, 0 );
}
printf("THis tcp client task is RUN! \r\n");
}
3、定时器任务
这里定时器只有一件事情,就是在连接正常后将缓存发出去
static void clientTimerCallback( TimerHandle_t childTaskTimer )
{
uint8_t i;
for(i=0;i<CLIENT_CONN_NUM;i++)
{
if (g_Cccb[i].stat==2)
sendDataFromTimer(&g_Cccb[i]);
}
testSendData(); //数据发送测试
}
4、数据发送缓存
在连接没有建立或者正在建立时,将数据存入缓存,这里用一个链表来实现。目前只缓存中断连接后的若干数据,缓存满后就不存了,当然也可以改用环形缓存不间断缓存。
struct sendDataBufItem_t
{
struct sendDataBufItem_t * next;
uint8_t *data;
uint16_t size;
uint8_t connId;
};
struct sendDataBuf_t
{
struct sendDataBufItem_t head;
struct sendDataBufItem_t end;
uint16_t num;
};
static struct sendDataBuf_t sendDataBuf;
static void sendDataBufInit(void)
{
static uint8_t sendDataBufSta;
if (sendDataBufSta==0)
{
sendDataBuf.head .next = &(sendDataBuf.end );
sendDataBuf.head .connId =0xff;
sendDataBuf.end .next = NULL ;
sendDataBufSta=1;
}
}
err_t addSendDataBuf(uint8_t *data,uint16_t dataSize,uint8_t connId)
{
uint8_t *dataTemp;
struct sendDataBufItem_t * sendDataBufItem;
sendDataBufInit();
if (dataSize >CLIENT_SEND_SIZEMAX) return MYERR_ADD_BUF_ERR;
if (sendDataBuf.num >CLIENT_SENDBUF_MAX) return MYERR_ADD_BUF_ERR;
dataTemp = pvPortMalloc(dataSize);
if (dataTemp == NULL ) return MYERR_ADD_BUF_ERR;
sendDataBufItem = pvPortMalloc (sizeof(struct sendDataBufItem_t) );
if (sendDataBufItem