修复多连接的问题

This commit is contained in:
2026-07-19 15:27:49 +08:00
parent 9ed4c22022
commit e06d849007
38 changed files with 2475 additions and 1953 deletions

View File

@@ -1,34 +1,26 @@
/*
* 模块名称Network Select Implementation
* 模块功能I/O 多路复用实现,包select poll 模式
* 用于同时监控多个 Socket 的读写事件
* 适用平台STM32F4 系列CH395F 以太网芯片)
* 作者:王建锋
* 创建日期2026-07-18
* 修改记录:
*/
* 模块功能I/O 多路复用实现,包<EFBFBD>?select <EFBFBD>?poll 模式<EFBFBD>? * 用于同时监控多个 Socket 的读写事<E58699>? * 适用平台STM32F4 系列CH395F 以太网芯片)
* 作者王建<EFBFBD>? * 创建日期<E697A5>?026-07-18
* 修改记录<EFBFBD>? */
#include "net_select.h"
#include "net_socket.h"
#include "ch395f.h"
/*
* 私有函数声明
*/
* 私有函数声明<EFBFBD>? */
static int check_socket_readable(int sockfd);
static int check_socket_writable(int sockfd);
static int check_socket_error(int sockfd);
/*
* 公共函数实现
*/
* 公共函数实现<EFBFBD>? */
/*
* 函数功能I/O 多路复用select 模式
*/
* 函数功能I/O 多路复用select 模式<EFBFBD>? */
int net_select(int nfds, net_fd_set *readfds, net_fd_set *writefds,
net_fd_set *exceptfds, net_timeval *timeout)
{
net_fd_set *exceptfds, net_timeval *timeout) {
uint32_t start_tick;
uint32_t timeout_ms = 0;
net_fd_set result_read = {0};
@@ -38,56 +30,46 @@ int net_select(int nfds, net_fd_set *readfds, net_fd_set *writefds,
int i;
/* 计算超时时间 */
if (timeout != NULL)
{
if (timeout != NULL) {
timeout_ms = (uint32_t)(timeout->tv_sec * 1000) +
(uint32_t)(timeout->tv_usec / 1000);
}
start_tick = HAL_GetTick();
while (1)
{
/* 轮询所有 Socket */
while (1) {
/* 轮询所<E8AFA2>?Socket */
net_poll();
ready_count = 0;
/* 检查哪Socket 有事*/
for (i = 0; i < nfds && i < NET_MAX_SOCKETS; i++)
{
net_sock_t *sock = net_get_sock(i);
/* 检查哪<EFBFBD>?Socket 有事<EFBFBD>?*/
for (i = 0; i < nfds && i < NET_MAX_SOCKETS; i++) {
net_sock_t *p_sock = net_get_sock(i);
if (sock == NULL)
{
if (p_sock == NULL) {
continue;
}
/* 检查可读事*/
if (readfds != NULL && NET_FD_ISSET(i, readfds))
{
if (check_socket_readable(i))
{
/* 检查可读事<EFBFBD>?*/
if (readfds != NULL && NET_FD_ISSET(i, readfds)) {
if (check_socket_readable(i)) {
NET_FD_SET(i, &result_read);
ready_count++;
}
}
/* 检查可写事*/
if (writefds != NULL && NET_FD_ISSET(i, writefds))
{
if (check_socket_writable(i))
{
/* 检查可写事<EFBFBD>?*/
if (writefds != NULL && NET_FD_ISSET(i, writefds)) {
if (check_socket_writable(i)) {
NET_FD_SET(i, &result_write);
ready_count++;
}
}
/* 检查异常事*/
if (exceptfds != NULL && NET_FD_ISSET(i, exceptfds))
{
if (check_socket_error(i))
{
/* 检查异常事<EFBFBD>?*/
if (exceptfds != NULL && NET_FD_ISSET(i, exceptfds)) {
if (check_socket_error(i)) {
NET_FD_SET(i, &result_except);
ready_count++;
}
@@ -95,17 +77,14 @@ int net_select(int nfds, net_fd_set *readfds, net_fd_set *writefds,
}
/* 有事件就绪,返回 */
if (ready_count > 0)
{
if (ready_count > 0) {
break;
}
/* 超时检*/
if (timeout != NULL)
{
/* 超时检<EFBFBD>?*/
if (timeout != NULL) {
if (timeout_ms > 0 &&
(HAL_GetTick() - start_tick) >= timeout_ms)
{
(HAL_GetTick() - start_tick) >= timeout_ms) {
break; /* 超时返回 0 */
}
}
@@ -115,16 +94,13 @@ int net_select(int nfds, net_fd_set *readfds, net_fd_set *writefds,
}
/* 复制结果 */
if (readfds != NULL)
{
if (readfds != NULL) {
readfds->fd_bits = result_read.fd_bits;
}
if (writefds != NULL)
{
if (writefds != NULL) {
writefds->fd_bits = result_write.fd_bits;
}
if (exceptfds != NULL)
{
if (exceptfds != NULL) {
exceptfds->fd_bits = result_except.fd_bits;
}
@@ -132,95 +108,79 @@ int net_select(int nfds, net_fd_set *readfds, net_fd_set *writefds,
}
/*
* 函数功能I/O 多路复用poll 模式
*/
int net_poll_events(net_pollfd *fds, int nfds, int timeout)
{
* 函数功能I/O 多路复用poll 模式<EFBFBD>? */
int net_poll_events(net_pollfd *fds, int nfds, int timeout) {
uint32_t start_tick;
int ready = 0;
int i;
if (fds == NULL || nfds <= 0)
{
if (fds == NULL || nfds <= 0) {
return -1;
}
start_tick = HAL_GetTick();
while (1)
{
while (1) {
/* 轮询 */
net_poll();
ready = 0;
for (i = 0; i < nfds; i++)
{
for (i = 0; i < nfds; i++) {
fds[i].revents = 0;
/* 检fd 有效*/
if (fds[i].fd < 0 || fds[i].fd >= NET_MAX_SOCKETS)
{
/* 检<EFBFBD>?fd 有效<EFBFBD>?*/
if (fds[i].fd < 0 || fds[i].fd >= NET_MAX_SOCKETS) {
fds[i].revents |= NET_POLLNVAL;
ready++;
continue;
}
net_sock_t *sock = net_get_sock(fds[i].fd);
net_sock_t *p_sock = net_get_sock(fds[i].fd);
if (sock == NULL)
{
if (p_sock == NULL) {
fds[i].revents |= NET_POLLNVAL;
ready++;
continue;
}
/* 检查可*/
if (fds[i].events & NET_POLLIN)
{
if (check_socket_readable(fds[i].fd))
{
/* 检查可<EFBFBD>?*/
if (fds[i].events & NET_POLLIN) {
if (check_socket_readable(fds[i].fd)) {
fds[i].revents |= NET_POLLIN;
ready++;
}
}
/* 检查可*/
if (fds[i].events & NET_POLLOUT)
{
if (check_socket_writable(fds[i].fd))
{
/* 检查可<EFBFBD>?*/
if (fds[i].events & NET_POLLOUT) {
if (check_socket_writable(fds[i].fd)) {
fds[i].revents |= NET_POLLOUT;
ready++;
}
}
/* 检查错*/
if (check_socket_error(fds[i].fd))
{
/* 检查错<EFBFBD>?*/
if (check_socket_error(fds[i].fd)) {
fds[i].revents |= NET_POLLERR;
ready++;
}
/* 检查挂起(连接断开 */
if (sock->state == NET_SOCK_STATE_TCP_ACCEPT ||
sock->state == NET_SOCK_STATE_CLOSED)
{
/* 检查挂起(连接断开<EFBFBD>?*/
if (p_sock->state == NET_SOCK_STATE_TCP_ACCEPT ||
p_sock->state == NET_SOCK_STATE_CLOSED) {
fds[i].revents |= NET_POLLHUP;
ready++;
}
}
if (ready > 0)
{
if (ready > 0) {
break;
}
/* 超时检*/
if (timeout >= 0)
{
if ((HAL_GetTick() - start_tick) >= (uint32_t)timeout)
{
/* 超时检<EFBFBD>?*/
if (timeout >= 0) {
if ((HAL_GetTick() - start_tick) >= (uint32_t)timeout) {
break;
}
}
@@ -232,36 +192,29 @@ int net_poll_events(net_pollfd *fds, int nfds, int timeout)
}
/*
* 私有函数实现
*/
* 私有函数实现<EFBFBD>? */
/*
* 函数功能:检Socket 是否可读
* 返回值1 可读0 不可
*/
static int check_socket_readable(int sockfd)
{
net_sock_t *sock;
* 函数功能:检<EFBFBD>?Socket 是否可读
* 返回值1 可读<EFBFBD>? 不可<EFBFBD>? */
static int check_socket_readable(int sockfd) {
net_sock_t *p_sock;
uint16_t recv_len;
sock = net_get_sock(sockfd);
if (sock == NULL)
{
p_sock = net_get_sock(sockfd);
if (p_sock == NULL) {
return 0;
}
/* 监听 Socket 有新连接时可*/
if (sock->state == NET_SOCK_STATE_LISTENING)
{
/* 监听 Socket 有新连接时可<EFBFBD>?*/
if (p_sock->state == NET_SOCK_STATE_LISTENING) {
return 1;
}
/* 已建立连接的 Socket 有数据可*/
if (sock->state == NET_SOCK_STATE_ESTABLISHED)
{
/* 已建立连接的 Socket 有数据可<EFBFBD>?*/
if (p_sock->state == NET_SOCK_STATE_ESTABLISHED) {
recv_len = ch395f_get_recv_len(sockfd);
if (recv_len > 0)
{
if (recv_len > 0) {
return 1;
}
}
@@ -270,24 +223,19 @@ static int check_socket_readable(int sockfd)
}
/*
* 函数功能:检Socket 是否可写
* 返回值1 可写0 不可
*/
static int check_socket_writable(int sockfd)
{
net_sock_t *sock;
* 函数功能:检<EFBFBD>?Socket 是否可写
* 返回值1 可写<EFBFBD>? 不可<EFBFBD>? */
static int check_socket_writable(int sockfd) {
net_sock_t *p_sock;
sock = net_get_sock(sockfd);
if (sock == NULL)
{
p_sock = net_get_sock(sockfd);
if (p_sock == NULL) {
return 0;
}
/* 已建立连接的 Socket 发送缓冲区空闲时可*/
if (sock->state == NET_SOCK_STATE_ESTABLISHED)
{
if (sock->send_ready)
{
/* 已建立连接的 Socket 发送缓冲区空闲时可<EFBFBD>?*/
if (p_sock->state == NET_SOCK_STATE_ESTABLISHED) {
if (p_sock->send_ready) {
return 1;
}
}
@@ -296,22 +244,17 @@ static int check_socket_writable(int sockfd)
}
/*
* 函数功能:检Socket 是否有错
* 返回值1 有错误0 无错误
*/
static int check_socket_error(int sockfd)
{
net_sock_t *sock;
* 函数功能:检<EFBFBD>?Socket 是否有错<EFBFBD>? * 返回值1 有错误0 无错<E697A0>? */
static int check_socket_error(int sockfd) {
net_sock_t *p_sock;
/* 无效 fd 视为错误 */
if (sockfd < 0 || sockfd >= NET_MAX_SOCKETS)
{
if (sockfd < 0 || sockfd >= NET_MAX_SOCKETS) {
return 1;
}
sock = net_get_sock(sockfd);
if (sock == NULL)
{
p_sock = net_get_sock(sockfd);
if (p_sock == NULL) {
return 1; /* 未使用的 Socket 视为错误 */
}