前言
实现多个客户端同时连接 初步代码结构已经实现完成(通过轮训的方式)
# if 1
# include <string.h>
# include "lwip/api.h"
# include "FreeRTOS.h"
# include "task.h"
# include "usart.h"
# include "lwip_comm.h"
# define CLIENT_LIST_SIZE 3
typedef struct {
u8_t stat;
struct netconn * conn;
struct netbuf * net_buf;
ip_addr_t ip;
u16_t port;
# define BUF_SIZE 1024
u8_t buf[ BUF_SIZE] ;
} client_pcb;
static TaskHandle_t tcp_server;
static TaskHandle_t tcp_client;
static void tcp_server_entity ( void * args) ;
client_pcb client_list[ CLIENT_LIST_SIZE] ;
static void tcp_client_request_entity ( void * args) ;
void netconn_tcp_server_create_thread ( ) {
memset ( client_list, 0 , sizeof ( client_list) ) ;
xTaskCreate (
( TaskFunction_t) tcp_server_entity,
"tcp_server" ,
256 ,
NULL ,
10 ,
& tcp_server
) ;
xTaskCreate (
( TaskFunction_t) tcp_client_request_entity,
"tcp_client" ,
256 ,
NULL ,
9 ,
& tcp_client
) ;
}
# define TCP_SERVER_RX_BUFSIZE 1500
static struct netconn * conn;
static struct netconn * client_conn;
static uint8_t remot_addr[ 4 ] = { 0 } ;
static u16_t port;
static ip_addr_t ipaddr;
static u8_t tcp_server_recvbuf[ TCP_SERVER_RX_BUFSIZE] = { 0 } ;
static void tcp_server_entity ( void * args) {
err_t err;
conn = netconn_new ( NETCONN_TCP) ;
netconn_bind ( conn, IP_ADDR_ANY, 8080 ) ;
netconn_listen ( conn) ;
conn-> recv_timeout = 10 ;
struct netconn * cli_con;
while ( 1 ) {
begin_listen:
err = netconn_accept ( conn, & cli_con) ;
if ( err == ERR_OK) {
cli_con-> recv_timeout = 10 ;
for ( int i = 0 ; i < CLIENT_LIST_SIZE; ++ i) {
if ( client_list[ i] . stat == 0 ) {
netconn_getaddr ( cli_con, & client_list[ i] . ip, & client_list[ i] . port, 0 ) ;
remot_addr[ 3 ] = ( uint8_t ) ( client_list[ i] . ip. addr >> 24 ) ;
remot_addr[ 2 ] = ( uint8_t ) ( client_list[ i] . ip. addr >> 16 ) ;
remot_addr[ 1 ] = ( uint8_t ) ( client_list[ i] . ip. addr >> 8 ) ;
remot_addr[ 0 ] = ( uint8_t ) ( client_list[ i] . ip. addr) ;
printf ( "主机%d.%d.%d.%d连接上服务器,主机端口号为:%d\r\n" ,
remot_addr[ 0 ] , remot_addr[ 1 ] , remot_addr[ 2 ] , remot_addr[ 3 ] , client_list[ i] . port) ;
client_list[ i] . stat = 1 ;
client_list[ i] . conn = cli_con;
goto begin_listen;
}
}
netconn_close ( cli_con) ;
netconn_delete ( cli_con) ;
}
vTaskDelay ( 10 ) ;
}
}
static void tcp_client_request_entity ( void * args) {
client_pcb * p_client;
err_t err;
u32_t data_len;
while ( 1 ) {
for ( int i = 0 ; i < CLIENT_LIST_SIZE; ++ i) {
p_client = & client_list[ i] ;
if ( p_client-> stat == 1 ) {
err = netconn_recv ( p_client-> conn, & p_client-> net_buf) ;
switch ( err) {
case ERR_OK: {
portDISABLE_INTERRUPTS ( ) ;
memset ( p_client-> buf, 0 , BUF_SIZE) ;
for ( struct pbuf * q = p_client-> net_buf-> p; q != NULL ; q = q-> next)
{
if ( q-> len > ( BUF_SIZE - data_len) ) {
memcpy ( p_client-> buf + data_len, q-> payload, BUF_SIZE - data_len) ;
break ;
} else {
memcpy ( p_client-> buf + data_len, q-> payload, q-> len) ;
}
data_len += q-> len;
if ( data_len > BUF_SIZE) break ;
}
portENABLE_INTERRUPTS ( ) ;
netconn_write ( p_client-> conn, p_client-> buf, data_len, NETCONN_COPY) ;
data_len = 0 ;
netbuf_delete ( p_client-> net_buf) ;
break ;
}
case ERR_CLSD:
case ERR_RST: {
goto release_conn_tag;
}
default :
if ( g_lwipdev. link_status == LWIP_LINK_OFF) {
printf ( "物理连线出现问题\r\n" ) ;
goto release_conn_tag;
}
}
continue ;
release_conn_tag:
{
netconn_close ( p_client-> conn) ;
netconn_delete ( p_client-> conn) ;
p_client-> stat = 0 ;
}
}
vTaskDelay ( 10 ) ;
}
}
}
# endif
测试结果