LwIP TCP 客户端 保活功能

LwIP TCP 客户端 保活功能

之前在做项目的时候,有这么一种情况是TCP客户端是没有响应的。首先正常连接服务器,然后断开网线,TCP 客户端没有任何响应,可是再插上网线就永远也连接不到服务器了。

这个现象想必大家经常遇到,不知道你们是怎么处理的。LwIP毕竟是一个用了这么久的协议栈,必定有处理方式,那就是保活功能,这个功能在服务器模式下,是自动开启的,我们不需要注意。

首先需要在lwipopts.h文件中添加如下宏定义,目的是打开保活功能,这些数值根据需求自己更改。

#define LWIP_TCP_KEEPALIVE        1
#define TCP_KEEPIDLE_DEFAULT      5000UL
#define TCP_KEEPINTVL_DEFAULT     1000UL
#define TCP_KEEPCNT_DEFAULT       5UL
#define TCP_MAXIDLE               TCP_KEEPCNT_DEFAULT * TCP_KEEPINTVL_DEFAULT

第一条为打开保活功能,第二条为服务器和客户端5秒内没有数据传输,就开始探测,第三条为每1秒探测一次,第四条为探测5次,最后一条为服务器和客户端没有数据传输最大时间。实际上后边的4条可以不添加,使用默认配置,就是时间有点长为2小时。

其次新建客户端代码如下,配置连接打开保活功能。

struct netconn *TcpClientConn;
TcpClientConn = netconn_new(NETCONN_TCP);
#if LWIP_TCP_KEEPALIVE
TcpClientConn->pcb.tcp->so_options |= SOF_KEEPALIVE;
#endif /* End LWIP_TCP_KEEPALIVE */
err_t err = netconn_connect(TcpClientConn,&ServerIP,ServerPort);
struct netbuf *ClientDataBuf;
err = netconn_recv(TcpClientConn,&ClientDataBuf);
if(err == ERR_OK)
{
    //这里添加处理接收到的数据部分
}
else
{
    //断线就会进入这里
    netconn_disconnect(TcpClientConn);
    netconn_delete(TcpClientConn);
}
netbuf_delete(ClientDataBuf);

以上为客户端接收部分,当然在该文件前需要引入以下两个头文件,不然会报错的。

#include "lwip/tcp.h"
#include "lwip/ip.h"

这样就OK了,以上代码只是简单示例,需要修改逻辑才能适合你的应用。

以下是一个使用LWIP库编写的C语言TCP客户端代码示例,其中包括了机制: ```c #include "lwip/sockets.h" #include "lwip/sys.h" #include "lwip/netdb.h" #define SERVER_IP "192.168.0.1" #define SERVER_PORT 12345 int main(void) { int sockfd; struct sockaddr_in server_addr; char buf[1024]; int len; sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { perror("socket"); return -1; } server_addr.sin_family = AF_INET; server_addr.sin_port = htons(SERVER_PORT); server_addr.sin_addr.s_addr = inet_addr(SERVER_IP); if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { perror("connect"); return -1; } // 设置TCP机制 int keepAlive = 1; // 开启keepalive属性 int keepIdle = 60; // 如该连接在60秒内没有任何数据往来,则进行探测 int keepInterval = 5; // 探测时包的时间间隔为5 秒 int keepCount = 3; // 探测尝试的次数。如果第1次探测包就收到响应了,则后2次的不再。 setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepAlive, sizeof(keepAlive)); setsockopt(sockfd, SOL_TCP, TCP_KEEPIDLE, (void*)&keepIdle, sizeof(keepIdle)); setsockopt(sockfd, SOL_TCP, TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval)); setsockopt(sockfd, SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount)); while (1) { printf("Input message to send: "); fgets(buf, sizeof(buf), stdin); len = send(sockfd, buf, strlen(buf), 0); if (len < 0) { perror("send"); break; } memset(buf, 0, sizeof(buf)); len = recv(sockfd, buf, sizeof(buf), 0); if (len < 0) { perror("recv"); break; } printf("Received message: %s\n", buf); } close(sockfd); return 0; } ``` 这个客户端代码使用了LWIP库提供的socket函数进行套接字操作,连接到指定的服务器IP和端口。在连接建立后,通过设置setsockopt函数来开启TCP机制,确连接不会因为长时间未通信而被关闭。然后进入循环,用户可以输入要送的消息,程序将其送给服务器并等待接收对方的回复。循环一直执行直到用户输入exit或者生错误。最后关闭套接字并退出程序。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值