网站怎么做可以被收录,wordpress没人用,网页版传奇游戏排行榜,宝塔里面一个服务器做多个网站目录 一、问题描述
二、项目构成
三、问题解决
1.问题代码
2.解决思路
3.核心代码#xff1a;
四、完整代码
1.监测网口插入拔出任务
2.TCP任务
3.创建tcp任务
4.删除tcp任务
五、总结 一、问题描述
最近遇到一个问题#xff0c;就是我的stm32设备作为tcp客户端…目录 一、问题描述
二、项目构成
三、问题解决
1.问题代码
2.解决思路
3.核心代码
四、完整代码
1.监测网口插入拔出任务
2.TCP任务
3.创建tcp任务
4.删除tcp任务
五、总结 一、问题描述
最近遇到一个问题就是我的stm32设备作为tcp客户端和上位机交互如果在连接过程中网线被拔断等待时间稍微长一点再插上的话tcp将不能再连接到服务器端除非重启设备所以我开始研究怎么解决这个lwip的小问题。 二、项目构成
MCU : STM32F429IGTx
网口芯片 LAN8720
操作系统 UCOSIII
协议栈LWIP
调试工具sscom5.13.1可开启TCP服务端 三、问题解决
1.问题代码 我们写了一个socket的tcp客户端作为一个单独的任务执行recv这个函数阻塞没数据的时候一直被阻塞但是不影响其它任务有了数据发过来或者正常的tcp断开recv函数就会收到数据往下执行但是这时候我们遇到了一个问题那就是TCP连接状态下网线被拔出recv这个函数没有做任何的反应所以这便导致了recv这个函数一直被阻塞插上网线以后不能重新像服务器进行tcp连接理想状态下是recv函数应该也像正常tcp断开那样给我返回一个信号那样我就知道tcp中断了就去循环重新获取TCP连接可是并没有我们设备安装在现场难免会有网线被拔出的情况一拔出再插入tcp就连接不上了说不过去所以只能自己想办法解决这个问题。
2.解决思路
一开始的解决思路就是在tcp的recv下面加一个检测网线是否被插入的判断如果网线被拔出的话也break跳出当前while去上一级while里面进行tcp连接可是忽略了recv函数阻塞的问题网线被拔出recv没有数据根本不往下执行如果是netconn不阻塞的那种倒是可以所以这个方案否了。
后来琢磨recv不是阻塞么不如重新创建一个任务检测网口的网线插入状态把这个tcp任务重新启动呢最开始想到了挂起再恢复后来发现恢复以后任务还会继续在阻塞里面解决不了问题。想了想只能是拔出网线后删除tcp任务再重新创建了为避免资源浪费检测到网线拔出就删除tcp任务检测到网线插入就创建tcp任务。
3.核心代码
HAL库 LAN8720_ReadPHY(PHY_BSR) PHY_LINKED_STATUS
标准库 ETH_ReadPHYRegister(LAN8720_PHY_ADDRESS, PHY_BSR) PHY_Linked_Status)
如果网线是插入状态 代码的结果就是1
如果网线是拔出状态 代码的结果就是0
当tcp建立连接以后就一直去判断网线有没有被拔出如果被拔出了就删除tcp任务。当tcp没有建立连接的时候就一直去判断网线有没有被插入插入的话就创建tcp任务注意代码逻辑不要多次删除或者创建同一任务导致系统崩溃。
四、完整代码
1.监测网口插入拔出任务
u8 TCP_CONNECT_FLAG0;//TCP连接状态 0是未连接 1是已连接 2是重新创建了任务待连接//1.监测网口插入拔出任务
void key_task(void *pdata)
{u8 res;OS_ERR err; while(1){/**key KEY_Scan(0);if(keyKEY0_PRES) //发送数据{LED0 !LED0;}**/if(TCP_CONNECT_FLAG1){if(!(LAN8720_ReadPHY(PHY_BSR) PHY_LINKED_STATUS)){//删除tcp任务TCP_CONNECT_FLAG0;tcp_deletetask();}}else if(TCP_CONNECT_FLAG0){if((LAN8720_ReadPHY(PHY_BSR) PHY_LINKED_STATUS)){//打开tcp任务TCP_CONNECT_FLAG2;tcp_starttask();}}OSTimeDlyHMSM(0,0,0,100,OS_OPT_TIME_HMSM_STRICT,err); //延时2s}
}2.TCP任务
#define PORT 5001
#define RECV_DATA (1024)
#define SERV_IP_ADDR 192.168.0.222
#define SERV_PORT 8088
unsigned char rec_buffers[1024]{0X66,0x14,0x97,0x0F,0x1D,0xEA\n};
unsigned char rec_buffers2[1024]{\n};
extern u8 TCP_CONNECT_FLAG;
int sock-1;void tcp_thread(void *arg)
{OS_ERR err;int block 1;struct sockaddr_in Serv_addr;//char*recv_data;int recv_data_len;/*为recv_data申请内存空间 申请成功返回内存空间首地址 失败返回NULL*///recv_data(char*)malloc(RECV_DATA);//if(recv_dataNULL){//printf(Mallo memory failed\r\n);// }while(1){if(sock!-1){closesocket(sock);sock-1;}/* 为sockaddr_in结构体成员赋值用于以下的connect绑定 参数protocol在TCP/TCP两种协议下均为0 *//*套接字申请成功返回Socket描述符(int类型) 失败返回-1*/socksocket(AF_INET,SOCK_STREAM,0);if(sock0){// printf(Socket error\n);OSTimeDlyHMSM(0,0,0,10,OS_OPT_TIME_HMSM_STRICT,err);continue;}//ioctlsocket(sock,FIONBIO,block); /*TCP/IP – IPv4*/Serv_addr.sin_familyAF_INET;/*绑定远端服务器的端口*/Serv_addr.sin_porthtons(SERV_PORT);/*绑定远端服务器的ip*/Serv_addr.sin_addr.s_addrinet_addr(SERV_IP_ADDR);/* 清空sockaddr_in结构体内存空间 sin_zero是为了让sockaddr与sockaddr_in两个数据结构保持大小相同而保留的空字节 */memset((Serv_addr.sin_zero), 0, sizeof(Serv_addr.sin_zero)); /* 连接远端服务器 */if (connect(sock, (struct sockaddr *)Serv_addr, sizeof(struct sockaddr)) -1) {//printf(Connect failed!\n);closesocket(sock);OSTimeDlyHMSM(0,0,0,10,OS_OPT_TIME_HMSM_STRICT,err);continue;}TCP_CONNECT_FLAG1;//printf(Connect to tcp server successful!\n); while(1){ /* 成功接收到数据返回接收的数据长度 */recv_data_len recv(sock, rec_buffers2, RECV_DATA, 0);if (recv_data_len 0){ break; }else{write(sock,rec_buffers,1024);}/* 串口打印接收的数据内容 *///printf(recv:%s\n,recv_data);/* 发送数据内容 */OSTimeDlyHMSM(0,0,0,5,OS_OPT_TIME_HMSM_STRICT,err); }OSTimeDlyHMSM(0,0,0,5,OS_OPT_TIME_HMSM_STRICT,err);}}
3.创建tcp任务
void tcp_starttask(){OS_ERR err;CPU_SR_ALLOC();OS_CRITICAL_ENTER();//进入临界区OSTaskCreate((OS_TCB * )TcpTaskTCB, (CPU_CHAR * )tcp task, (OS_TASK_PTR )tcp_thread, (void * )0, (OS_PRIO )TCP_PRIO, (CPU_STK * )TCP_TASK_STK[0], (CPU_STK_SIZE)TCP_STK_SIZE/10, (CPU_STK_SIZE)TCP_STK_SIZE, (OS_MSG_QTY )0, (OS_TICK )0, (void * )0, (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,(OS_ERR * )err);OS_CRITICAL_EXIT(); //退出临界区
}
4.删除tcp任务
void tcp_deletetask(){OS_ERR err;CPU_SR_ALLOC();OS_CRITICAL_ENTER();//进入临界区OSTaskDel((OS_TCB * )TcpTaskTCB,err);OS_CRITICAL_EXIT(); //退出临界区} 五、总结
算是解决了网线拔出再插入以后tcp不能重新建立连接的问题可能方法过于简单粗暴如果大佬有更好的方法解决这个问题欢迎交流指导。