前言
实现多个客户端同时连接 初步代码结构已经实现完成(通过轮训的方式)
# 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
测试结果