Freertos下,使用keepalive

平台:vitis2019.2
keepalive信号可以在某种异常情况下 断开连接,释放资源
server端和client端稍微有所区别,记录如下:
初始化函数如下

static void KeepaliveInit(int socket)
{
	int keepalive = 1;		//使能心跳机制
	setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE, (void*)&keepalive, sizeof(keepalive));
}
static void KeepaliveSetOpt(int socket)
{
	int keepidle = 3;		//发送心跳空闲周期 S
	int keepinterval = 1;	//发送心跳间隔 S
	int keepcount = 2;		//重发次数
	int flag = 1;			//不延时发送到合并包

	setsockopt(socket, IPPROTO_TCP, TCP_KEEPIDLE, (void*)&keepidle , 		sizeof(keepidle));
	setsockopt(socket, IPPROTO_TCP, TCP_KEEPINTVL, (void *)&keepinterval , 	sizeof(keepinterval));
	setsockopt(socket, IPPROTO_TCP, TCP_KEEPCNT, (void *)&keepcount , 		sizeof(keepcount));
	setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (void *)&flag , 			sizeof(flag));
}

client端代码如下:

int psNet0sock = (-1);
void psNet0_Thread(void *p)
{
	int read_bytes, ret ;
	struct sockaddr_in address;

	memset(&address, 0, sizeof(address));
	vTaskDelay(100);
	/* start packet receive thread - required for lwIP operation */
	sys_thread_new("xemacif_input_thread",
			(void(*)(void*))psNet0_xemacif_input_thread, &psNet0_netif,
			1024, DEFAULT_THREAD_PRIO);

	while(1){
		if(ETH_LINK_UP != eth_link_status){
			vTaskDelay(1000);
			continue;
		}
		netif_set_default(&psNet0_netif);
		netif_set_up(&psNet0_netif);

		if ((psNet0sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
			Debug("psNet0_netif: Error in creating Socket\r\n");
			continue;
		}
		//使能心跳机制 需要在socket之后
		KeepaliveInit(psNet0sock);
		address.sin_family = AF_INET;
		address.sin_port = htons(TCP_CONN_PORT);
		address.sin_addr.s_addr = inet_addr(TCP_SERVER_IP_ADDRESS);

		if (connect(psNet0sock, (struct sockaddr*)&address, sizeof(address)) < 0) {
//			Debug("psNet0_netif: Error on tcp_connect\r\n");
			close(psNet0sock);
			psNet0sock = -1;
			vTaskDelay(1000);
			continue;
		}
		KeepaliveSetOpt(psNet0sock);//需要在connect之后

		Debug("psNet0_netif sock = %d\r\n",psNet0sock);
		while(1)
		{
			read_bytes = lwip_recvfrom(psNet0sock, psNet0recv_buf, TCP_SEND_BUFSIZE, 0, NULL, NULL);
			if(read_bytes < 0){
				ret = lwip_close(psNet0sock);
				Debug("close sock[%d] = %d,  %d\r\n",psNet0sock,ret,read_bytes);
				break;
			}
			else if(read_bytes > 0){
//处理代码
			}
			else{
				ret = lwip_close(psNet0sock);
				Debug("close sock[%d] = %d,  %d\r\n",psNet0sock,ret,read_bytes);
				break;
			}
		}
		psNet0sock = -1;
		vTaskDelay(500);
	}
}

server端代码如下

void psNet0_Thread(void *p)
{
	int sock, new_sd;
	struct sockaddr_in address, remote;
	int size;

	memset(&address, 0, sizeof(address));
	vTaskDelay(100);
	/* start packet receive thread - required for lwIP operation */
	sys_thread_new("xemacif_input_thread",
			(void(*)(void*))psNet0_xemacif_input_thread, &psNet0_netif,
			1024, DEFAULT_THREAD_PRIO);

	while(1){
		if(ETH_LINK_UP != eth_link_status){
			vTaskDelay(1000);
			continue;
		}
		netif_set_default(&psNet0_netif);
		netif_set_up(&psNet0_netif);

		if ((sock = lwip_socket(AF_INET, SOCK_STREAM, 0)) < 0) {
			xil_printf("TCP server: Error creating Socket\r\n");
			continue;
		}
		//使能心跳机制 需要在socket之后
		KeepaliveInit(sock);
		address.sin_family = AF_INET;
		address.sin_port = htons(TCP_CONN_PORT);
		address.sin_addr.s_addr = INADDR_ANY;

		if (bind(sock, (struct sockaddr *)&address, sizeof (address)) < 0) {
			xil_printf("TCP server: Unable to bind to port %d\r\n",
					TCP_CONN_PORT);
			close(sock);
			return;
		}

		if (listen(sock, 1) < 0) {
			xil_printf("TCP server: tcp_listen failed\r\n");
			close(sock);
			vTaskDelay(1000);
			continue;
		}
		while(1)
		{
			new_sd = accept(sock, (struct sockaddr *)&remote, (socklen_t *)&size);
			sys_thread_new("rcv thread", rcv_Thread, (void*)&new_sd, 1024, DEFAULT_THREAD_PRIO);
			KeepaliveSetOpt(new_sd);//需要在connect之后
		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值