|
发表于 2022-9-8 18:28:28
|
显示全部楼层
搞定了 TCP 新连接挤掉旧连接,防止客户端未主动断开连接,导致服务器一直处于连接中,其他客户端不能再连接的问题。
1、创建两个 socket,先用一个监听。
2、连接成功后,用另一个监听。
3、如果有新的连接,正在监听的那个连上,并主动关闭之前的那个旧连接。
下面代码中的 poll 函数在任务中循环调用就行了
/*
TCP Socket
*/
#define TCP_SOCKET_SERVER_PORT (7)
#define TCP_SOCKET_SERVER_LISTEN_LIST_SIZE (2)
static NX_TCP_SOCKET socket_server[TCP_SOCKET_SERVER_LISTEN_LIST_SIZE];
static uint8_t curr_socket_server = 0;
/**
* @brief TCP 服务器初始化
*
* @return UINT
*/
static UINT net_tcp_socket_server_init(void)
{
UINT status;
/* Create the TFTP server. */
for(int i=0; i<TCP_SOCKET_SERVER_LISTEN_LIST_SIZE; i++)
{
status = nx_tcp_socket_create(&ip, &socket_server[i], "Server socket",
NX_IP_NORMAL, NX_DONT_FRAGMENT, NX_IP_TIME_TO_LIVE, 100,
NX_NULL, NX_NULL);
if (status != NX_SUCCESS)
{
log_e("Create TCP socket server %d failed. status = 0x%02X.", i, status);
return status;
}
}
/* 开启当前 socket 监听. */
curr_socket_server = 0;
status = nx_tcp_server_socket_listen(&ip, TCP_SOCKET_SERVER_PORT, &socket_server[curr_socket_server], TCP_SOCKET_SERVER_LISTEN_LIST_SIZE, NX_NULL);
if(status != NX_SUCCESS)
{
log_e("TCP socket server %d listen failed. status = 0x%02X.", curr_socket_server, status);
nx_tcp_socket_delete(&socket_server[curr_socket_server]);
return status;
}
log_i("TCP socket server start OK.");
return status;
}
static UINT net_tcp_socket_server_poll(void)
{
UINT status = NX_SUCCESS;
NX_PACKET *packet_ptr;
ULONG soc_sta;
/* 获取当前 socket 的连接状态 */
nx_tcp_socket_info_get(&socket_server[curr_socket_server], NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, &soc_sta, NX_NULL, NX_NULL, NX_NULL);
if(soc_sta != NX_TCP_ESTABLISHED)
{
/* 当前 socket 未连接则尝试连接 */
status = nx_tcp_server_socket_accept(&socket_server[curr_socket_server], 200);
if(status)
{
nx_tcp_server_socket_unaccept(&socket_server[curr_socket_server]);
nx_tcp_server_socket_relisten(&ip, TCP_SOCKET_SERVER_PORT, &socket_server[curr_socket_server]);
}
else
{
/* 连接成功,则用备用 socket 继续监听端口 */
log_i("TCP socket server %d connected.", curr_socket_server);
nx_tcp_server_socket_relisten(&ip, TCP_SOCKET_SERVER_PORT, &socket_server[curr_socket_server^0x01]);
}
}
else
{
/* 当前 socket 已连接,则接收处理数据 */
status = nx_tcp_socket_receive(&socket_server[curr_socket_server], &packet_ptr, 200);
if((status != NX_SUCCESS) && (status != NX_NO_PACKET))
{
/* 产生 NX_NO_PACKET 错误则继续尝试接收,其他错误则断开连接 */
log_i("TCP socket server %d disconnected.", curr_socket_server);
nx_tcp_socket_disconnect(&socket_server[curr_socket_server], 200);
nx_tcp_server_socket_unaccept(&socket_server[curr_socket_server]);
/* 备用端口正在监听,互换备用 socket 和 当前 socket */
curr_socket_server ^= 1;
}
else
{
if(status == NX_SUCCESS)
{
status = nx_tcp_socket_send(&socket_server[curr_socket_server], packet_ptr, 200);
if(status)
{
log_e("TCP socket server %d send packet failed. status = 0x%02X", curr_socket_server, status);
nx_packet_release(packet_ptr);
}
}
/* 尝试备用 socket 是否有连接 */
status = nx_tcp_server_socket_accept(&socket_server[curr_socket_server^0x01], 0);
if(status == NX_SUCCESS)
{
/* 连接成功,则断开当前 socket 连接,并用当前 socket 继续监听端口 */
log_i("TCP socket server %d disconnected.", curr_socket_server);
nx_tcp_socket_disconnect(&socket_server[curr_socket_server], 200);
nx_tcp_server_socket_unaccept(&socket_server[curr_socket_server]);
nx_tcp_server_socket_relisten(&ip, TCP_SOCKET_SERVER_PORT, &socket_server[curr_socket_server]);
/* 互换备用 socket 和 当前 socket */
curr_socket_server ^= 1;
log_i("TCP socket server %d connected.", curr_socket_server);
}
}
}
return status;
}
|
|