**参考:**https://blog.csdn.net/Chuangke_Andy/article/details/113116289
**意义:**提高各平台lwip TCP/UDP 编程的兼容性,可以移植性
环境:
1.freertos
2.开启 LWIP_SOCKET & LWIP_TCP_KEEPALIVE
3.华大HC32F4A0(可以兼容)
编程
#include "lwip_keepalive.h"
#include "lwip/opt.h"
#include <lwip/sockets.h>
#include "lwip/sys.h"
#include "lwip/api.h"
#include "string.h"
//https://blog.csdn.net/Chuangke_Andy/article/details/121420376
#if (LWIP_SOCKET & LWIP_TCP_KEEPALIVE)
#define DEST_PORT (6134UL)//目标地址端口号
#define DEST_IP "192.168.2.195"/*目标地址IP,这里设为本机*/
#define MAX_DATA (1024UL)//接收到的数据最大程度
#define LWIP_KEEPALIVE_DEBUG_ENABLE 1
#if LWIP_KEEPALIVE_DEBUG_ENABLE
#define LWIP_KEEPALIVE_DEBUG printf
#else
#define LWIP_KEEPALIVE_DEBUG(...)
#endif
#define BUFF_SIZE (1024UL)
static char ReadBuff[BUFF_SIZE];
void lwip_keepalive_thread(void *arg)
{
int sockfd, n, i, ret;
struct sockaddr_in dest_addr;
int so_keepalive_val = 1; //使能心跳机制
int tcp_keepalive_idle = 3; //发送心跳空闲周期 S
int tcp_keepalive_intvl = 3;//发送心跳间隔 S
int tcp_keepalive_cnt = 3; //重发次数
int tcp_nodelay = 1; //不延时发送到合并包
again:
//创建scoket
sockfd = socket(AF_INET, SOCK_STREAM, 0);
//使能心跳机制
setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &so_keepalive_val, sizeof(int));
dest_addr.sin_family = AF_INET;
dest_addr.sin_port = htons(DEST_PORT);
dest_addr.sin_addr.s_addr = inet_addr(DEST_IP);
inet_aton(DEST_IP,&dest_addr.sin_addr);/*将点分十进制转换成32位整型类型*/
if(connect(sockfd,(struct sockaddr*)&dest_addr,sizeof(struct sockaddr)) < 0)
{
//连接方法,传入句柄,目标地址和大小
//100ms去连接一次服务器
LWIP_KEEPALIVE_DEBUG("connect error\r\n");
close(sockfd);
vTaskDelay(100);
goto again;
}
//配置心跳检测参数 默认参数时间很长
setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE, &tcp_keepalive_idle, sizeof(int));
setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL, &tcp_keepalive_intvl, sizeof(int));
setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPCNT, &tcp_keepalive_cnt, sizeof(int));
setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &tcp_nodelay, sizeof(int));
LWIP_KEEPALIVE_DEBUG("server is connect ok\r\n");
for(;;)
{
//等待服务器发送数据
n = read(sockfd, ReadBuff, BUFF_SIZE);
if(n <= 0)
{
LWIP_KEEPALIVE_DEBUG("read socket error\r\n");
close(sockfd);
goto again;
}
//写回服务器
n = write(sockfd, ReadBuff, n);
if(n <= 0)
{
close(sockfd);
goto again;
}
}
}
#endif
void lwip_keepalive_init(void)
{
#if LWIP_SOCKET
sys_thread_new("lwip_keepalive_thread", lwip_keepalive_thread, NULL, 512, 4);
#endif
}