lwip对于同一端口支持多个连接,只需在上位机进行连接时,即accept 能连接到即可,直接上代码:
#ifndef _SOCKET_APP_H
#define _SOCKET_APP_H
#include "global_includes.h"
#define INVALID_SOCKET -1
void socket_app_init(void);
void socket_app_pool(void);
bool socket_upload_txdata(uint8* buf, uint16 len);
#endif
#include "socket_app.h"
#include "sys_info.h"
#include "user_info.h"
#include "sys_timer.h"
#include "rtx_data_analy.h"
#include "hmi_app_pool.h"
#include "lwip/sockets.h"
#if UDP_MULTSERVER
#include "mult_app.h"
#endif
static struct sys_data_info* net_sys_info = NULL;
#define TCP_SPLICE_ENABLE 0
#define TCP_MAX_CONNECTION 2 // 2 UDP_MULTSERVER
#define TCP_UNVALID_FD -1
#define NET_TXBUF_SIZE 1500
#define NET_RXBUF_SIZE 1500
uint8 net_rxbuf[NET_RXBUF_SIZE];
uint8 net_txbuf[NET_TXBUF_SIZE];
struct sockaddr_in tcp_local_addr;
struct sockaddr_in local_addr;
struct sockaddr_in remote_addr_temp;
enum
{
TCP_STATE_IDLE = 0,
TCP_STATE_HEAD,
TCP_STATE_DATA,
TCP_STATE_ANALYDATA,
};
#define NET_TCP_RXBUFSIZE 1500
#define NET_TCP_TXBUFSIZE 1500
#define NET_TCP_HEADLEN 4
uint8 net_tcp_rxbuf[NET_TCP_RXBUFSIZE];
uint16 net_tcp_lenoffset;
uint16 net_tcp_rxitem = 0;
uint16 net_tcp_packetlen = 0;
uint8 net_tcp_state = 0;
#define TCP_CLOSE(len,tcp_sockfd) {if(len<=0){close(tcp_sockfd);tcp_sockfd = TCP_UNVALID_FD;net_sys_info->debug_view_info->tcpupenable = false;}}
#if UDP_MULTSERVER
static int32 udp_multsockfd[UDP_MULTSERVER];
/****************************************************************************************
*函数名称: net_udpmult_init
*
*函数说明: 多UDP端口初始化
****************************************************************************************/
void net_udpmult_init(void)
{
uint8 i;
uint8 optval = 1;
for(i = 0; i < UDP_MULTSERVER; i++)
{
udp_multsockfd[i] = -1;
while(1)
{
rt_thread_delay(RT_TICK_PER_SECOND / 20);
memset(&local_addr, 0, sizeof(struct sockaddr_in));
local_addr.sin_family = AF_INET;
local_addr.sin_port = htons(NET_PORT + i);//本地端口
local_addr.sin_addr.s_addr = INADDR_ANY;
udp_multsockfd[i] = socket(AF_INET, SOCK_DGRAM, 0);
if(udp_multsockfd[i] <= 0)
{
continue;
}
setsockopt(udp_multsockfd[i], SOL_SOCKET, SO_BROADCAST, (void*)&optval, sizeof(optval));
if(bind(udp_multsockfd[i], (struct sockaddr*)&local_addr, sizeof(local_addr)) < 0)
{
continue;
}
break;
}
}
}
void net_udpmult_pool(void)
{
uint8 i;
uint32 len = 0;;
int rxlen = 0;
int txlen = 0;
int16 ret;
fd_set readset;
fd_set writeset;
struct timeval tv;
len = sizeof(struct sockaddr_in);
for(i = 0; i < UDP_MULTSERVER; i++)
{
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO(&readset);
FD_ZERO(&writeset);
FD_SET(udp_multsockfd[i], &readset);
FD_SET(udp_multsockfd[i], &writeset);
ret = select(udp_multsockfd[i] + 1, &readset, 0, 0, &tv);
if(ret > 0) //说明有就绪的文件描述符
{
if(FD_ISSET(udp_multsockfd[i], &readset)) //判断是否为读取的文件描述符集
{
rxlen = recvfrom(udp_multsockfd[i], net_rxbuf, NET_RXBUF_SIZE, 0, (struct sockaddr*)&remote_addr_temp, (socklen_t*)&len); //接收数据
if(rxlen)
{
if(lwip_recvbroad() != 0)
{
remote_addr_temp.sin_addr.s_addr = INADDR_BROADCAST;
}
net_sys_info->debug_view_info->sockfd = udp_multsockfd[i];
net_sys_info->debug_view_info->remote_udp_sockaddr = remote_addr_temp;
net_sys_info->debug_view_info->trans_type = TRANS_TYPE_UDP;
txlen = net_rxdata_analy(net_rxbuf, rxlen, net_txbuf, NET_TXBUF_SIZE, EXTERNAL);
if(txlen)
{
txlen = sendto(udp_multsockfd[i], net_txbuf, txlen, 0, (struct sockaddr*)&remote_addr_temp, sizeof(struct sockaddr_in));
hmi_busy_set(HMI_IO_BUSY);
if(txlen)
{
net_sys_info->temp_information->trans_count++;
}
}
else
{
#if !SYS_BOOT_DEVICE
mult_write(net_rxbuf, rxlen, (NET_PORT + i), udp_multsockfd[i], &remote_addr_temp);
#endif
}
}
}
}
}
}
#endif
#if TCP_SERVER
#define ACCEPT_SOCK_MAX 8
int tcp_listenfd[TCP_MAX_CONNECTION];
int tcp_connectfd[TCP_MAX_CONNECTION][ACCEPT_SOCK_MAX];
static int32 tcp_sockfd = -1;
/****************************************************************************************
*函数名称: net_tcp_pool
*
*函数说明: 网络tcp数据包处理函数
****************************************************************************************/
const int i32NetPort[TCP_MAX_CONNECTION] =
{
7000,
502
};
void net_tcp_init(void)
{
uint8 i;
uint8 j;
for(i = 0; i < TCP_MAX_CONNECTION; i++)
{
for(j = 0; j < ACCEPT_SOCK_MAX; j++)
{
tcp_connectfd[i][j] = TCP_UNVALID_FD;
}
while(1)
{
rt_thread_delay(RT_TICK_PER_SECOND / 20);
tcp_local_addr.sin_family = AF_INET;
tcp_local_addr.sin_port = htons(i32NetPort[i]);
tcp_local_addr.sin_len = sizeof(tcp_local_addr);
tcp_local_addr.sin_addr.s_addr = INADDR_ANY;
tcp_listenfd[i] = socket(AF_INET, SOCK_STREAM, 0);
if(tcp_listenfd[i] <= 0)
{
continue;
}
if(bind(tcp_listenfd[i], (struct sockaddr*) &tcp_local_addr, sizeof(tcp_local_addr)) < 0)
{
continue ;
}
if(listen(tcp_listenfd[i], TCP_MAX_CONNECTION) < 0)
{
continue;
}
break;
}
}
}
/****************************************************************************************
*函数名称: net_tcp_pool
*
*函数说明: 网络tcp数据包处理函数
****************************************************************************************/
#if 0
void net_tcp_pool(void)
{
static uint32 len = 0;;
static int rxlen = 0;
static int txlen = 0;
static int16 ret;
static uint8 i;
static fd_set readset;
static fd_set writeset;
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;
len = sizeof(struct sockaddr_in);
for(i = 0; i < TCP_MAX_CONNECTION; i++)
{
rxlen = 0;
FD_ZERO(&readset);
FD_ZERO(&writeset);
FD_SET(tcp_listenfd[i], &readset);
FD_SET(tcp_listenfd[i], &writeset);
ret = select(tcp_listenfd[i] + 1, &readset, &writeset, 0, &tv);
if(ret > 0)
{
if(FD_ISSET(tcp_listenfd[i], &readset))
{
tcp_sockfd = accept(tcp_listenfd[i], (struct sockaddr*)&remote_addr_temp, (socklen_t*)&len);
if(tcp_sockfd > 0)
{
// if(tcp_connectfd[i] != INVALID_SOCKET)
// {
// close(tcp_connectfd[i]);
// tcp_connectfd[i] = INVALID_SOCKET;
// }
tcp_connectfd[i] = tcp_sockfd;
net_sys_info->debug_view_info->tcp_sockfd = tcp_connectfd[i];
net_sys_info->debug_view_info->sockfd = tcp_connectfd[i];
net_tcp_state = TCP_STATE_IDLE;
int flag = 1;
/* set option at TCP level */ /* name of option */ /* the cast is historical cruft */ /* length of option value */
ret = setsockopt(tcp_sockfd, IPPROTO_TCP, TCP_NODELAY, (void*) &flag, sizeof(int));
}
}
}
if(tcp_connectfd[i] != TCP_UNVALID_FD)
{
FD_ZERO(&readset);
FD_ZERO(&writeset);
FD_SET(tcp_connectfd[i], &readset);
FD_SET(tcp_connectfd[i], &writeset);
ret = select(tcp_connectfd[i] + 1, &readset, &writeset, 0, &tv);
if(ret > 0)
{
if(FD_ISSET(tcp_connectfd[i], &readset) && FD_ISSET(tcp_connectfd[i], &writeset))
{
rxlen = recv(tcp_connectfd[i], net_rxbuf, NET_RXBUF_SIZE, 0);
if(rxlen <= 0)
{
close(tcp_connectfd[i]);
tcp_connectfd[i] = TCP_UNVALID_FD;
net_sys_info->debug_view_info->sockfd = TCP_UNVALID_FD;
net_sys_info->debug_view_info->tcp_sockfd = TCP_UNVALID_FD;
}
else
{
txlen = net_rxdata_analy(net_rxbuf, rxlen, net_txbuf, NET_TXBUF_SIZE, EXTERNAL);
if(txlen)
{
txlen = send(tcp_connectfd[i], net_txbuf, txlen, 0);
hmi_busy_set(HMI_IO_BUSY);
TCP_CLOSE(txlen, tcp_connectfd[i]);
}
hmi_busy_set(HMI_IO_BUSY);
}
}
}
}
}
}
#else
void net_tcp_pool(void)
{
static uint32 len = 0;;
static int rxlen = 0;
static int txlen = 0;
static int16 ret;
static uint8 i;
static uint8 j;
static fd_set readset;
static fd_set writeset;
static uint8 byport_ix = 0;
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;
len = sizeof(struct sockaddr_in);
for(i = 0; i < TCP_MAX_CONNECTION; i++)
{
rxlen = 0;
FD_ZERO(&readset);
FD_ZERO(&writeset);
FD_SET(tcp_listenfd[i], &readset);
FD_SET(tcp_listenfd[i], &writeset);
ret = select(tcp_listenfd[i] + 1, &readset, &writeset, 0, &tv);
if(ret > 0)
{
if(FD_ISSET(tcp_listenfd[i], &readset))
{
tcp_sockfd = accept(tcp_listenfd[i], (struct sockaddr*)&remote_addr_temp, (socklen_t*)&len);
if(tcp_sockfd > 0)
{
// if(tcp_connectfd[i] != INVALID_SOCKET)
// {
// close(tcp_connectfd[i]);
// tcp_connectfd[i] = INVALID_SOCKET;
// }
for(j = 0; j < ACCEPT_SOCK_MAX; j++)
{
if(tcp_connectfd[i][j] == INVALID_SOCKET)
{
break;
}
}
// j = (j == ACCEPT_SOCK_MAX) ? 0 : j;
if(j == ACCEPT_SOCK_MAX)
{
j = byport_ix;
byport_ix = (byport_ix + 1) % ACCEPT_SOCK_MAX;
}
if(tcp_connectfd[i][j] != INVALID_SOCKET)
{
close(tcp_connectfd[i][j]);
tcp_connectfd[i][j] = INVALID_SOCKET;
}
tcp_connectfd[i][j] = tcp_sockfd;
net_sys_info->debug_view_info->tcp_sockfd = tcp_connectfd[i][j];
net_sys_info->debug_view_info->sockfd = tcp_connectfd[i][j];
net_tcp_state = TCP_STATE_IDLE;
int flag = 1;
/* set option at TCP level */ /* name of option */ /* the cast is historical cruft */ /* length of option value */
ret = setsockopt(tcp_sockfd, IPPROTO_TCP, TCP_NODELAY, (void*) &flag, sizeof(int));
}
}
}
for(j = 0; j < ACCEPT_SOCK_MAX; j++)
{
if(tcp_connectfd[i][j] != TCP_UNVALID_FD)
{
FD_ZERO(&readset);
FD_ZERO(&writeset);
FD_SET(tcp_connectfd[i][j], &readset);
FD_SET(tcp_connectfd[i][j], &writeset);
ret = select(tcp_connectfd[i][j] + 1, &readset, &writeset, 0, &tv);
if(ret > 0)
{
if(FD_ISSET(tcp_connectfd[i][j], &readset) && FD_ISSET(tcp_connectfd[i][j], &writeset))
{
rxlen = recv(tcp_connectfd[i][j], net_rxbuf, NET_RXBUF_SIZE, 0);
if(rxlen <= 0)
{
close(tcp_connectfd[i][j]);
tcp_connectfd[i][j] = TCP_UNVALID_FD;
net_sys_info->debug_view_info->sockfd = TCP_UNVALID_FD;
net_sys_info->debug_view_info->tcp_sockfd = TCP_UNVALID_FD;
}
else
{
txlen = net_rxdata_analy(net_rxbuf, rxlen, net_txbuf, NET_TXBUF_SIZE, EXTERNAL);
if(txlen)
{
txlen = send(tcp_connectfd[i][j], net_txbuf, txlen, 0);
hmi_busy_set(HMI_IO_BUSY);
TCP_CLOSE(txlen, tcp_connectfd[i][j]);
}
hmi_busy_set(HMI_IO_BUSY);
}
}
}
}
}
}
}
#endif
#endif
/****************************************************************************************
*函数名称: socket_app_init
*
*函数说明: socket 应用初始化函数
****************************************************************************************/
void socket_app_init(void)
{
net_sys_info = sys_info_datainfoget();
#if TCP_SERVER
net_tcp_init();
#endif
#if UDP_MULTSERVER
net_udpmult_init();
#endif
}
/****************************************************************************************
*函数名称: socket_app_pool
*
*函数说明: 网络socket数据包处理函数
****************************************************************************************/
void socket_app_pool(void)
{
#if TCP_SERVER
net_tcp_pool();
#endif
#if UDP_MULTSERVER
net_udpmult_pool();
#endif
}