平台: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之后
}
}
}