前言
使用两个线程作为客户端中的收和发 使用线程挂起和线程恢复的api来实现 接收线程必须要保证在处理连接状态才能进行接收。
Demo
# include <string.h>
# include "lwip/api.h"
# include "FreeRTOS.h"
# include "task.h" # define TCP_CLIENT_RX_BUFSIZE 256 static void tcp_client_send ( void * ) ; static void tcp_client_rec ( void * ) ; static TaskHandle_t client_send_handle;
static TaskHandle_t client_rec_handle;
static ip_addr_t server_ipaddr, loca_ipaddr;
static uint16_t server_port = 8080 ;
static struct netconn * tcp_conn;
static uint8_t tcp_client_recvbuf[ TCP_CLIENT_RX_BUFSIZE] = { 0 } ; void create_netconn_tcp_client_thread ( ) { xTaskCreate ( ( TaskFunction_t) tcp_client_send, ( const char * ) "tcp_client_send" , ( uint16_t ) 256 , ( void * ) NULL , ( UBaseType_t) 10 , ( TaskHandle_t * ) & client_send_handle) ; xTaskCreate ( ( TaskFunction_t) tcp_client_rec, ( const char * ) "tcp_client_rec" , ( uint16_t ) 256 , ( void * ) NULL , ( UBaseType_t) 11 , ( TaskHandle_t * ) & client_rec_handle) ; } const char * tcp_client_sendbuf = "Apollo STM32F4/F7 NETCONN TCP Client send data\r\n" ;
static void tcp_client_send ( void * arg) { err_t err, recv_err; IP4_ADDR ( & server_ipaddr, 192 , 168 , 8 , 2 ) ; while ( 1 ) { tcp_conn = netconn_new ( NETCONN_TCP) ; err = netconn_connect ( tcp_conn, & server_ipaddr, server_port) ; if ( err != ERR_OK) { netconn_delete ( tcp_conn) ; printf ( "连接失败....等待重新连接\r\n" ) ; vTaskDelay ( 1000 ) ; continue ; } else { vTaskResume ( client_rec_handle) ; printf ( "连接...ok\r\n" ) ; } while ( 1 ) { err = netconn_write ( tcp_conn, tcp_client_sendbuf, strlen ( ( char * ) tcp_client_sendbuf) , NETCONN_COPY) ; if ( err != ERR_OK) { printf ( "发送失败\r\n" ) ; netconn_close ( tcp_conn) ; netconn_delete ( tcp_conn) ; break ; } vTaskDelay ( 1000 ) ; } }
} static void tcp_client_rec ( void * arg) { err_t recv_err; uint32_t data_len; struct pbuf * q; struct netbuf * recvbuf; vTaskSuspend ( client_rec_handle) ; while ( 1 ) { if ( ( recv_err = netconn_recv ( tcp_conn, & recvbuf) ) == ERR_OK) { portDISABLE_INTERRUPTS ( ) ; memset ( tcp_client_recvbuf, 0 , TCP_CLIENT_RX_BUFSIZE) ; for ( q = recvbuf-> p; q != NULL ; q = q-> next) { if ( q-> len > ( TCP_CLIENT_RX_BUFSIZE - data_len) ) memcpy ( tcp_client_recvbuf + data_len, q-> payload, ( TCP_CLIENT_RX_BUFSIZE - data_len) ) ; else memcpy ( tcp_client_recvbuf + data_len, q-> payload, q-> len) ; data_len += q-> len; if ( data_len > TCP_CLIENT_RX_BUFSIZE) break ; } portENABLE_INTERRUPTS ( ) ; data_len = 0 ; printf ( "%s" , tcp_client_recvbuf) ; netbuf_delete ( recvbuf) ; } else if ( recv_err == ERR_CLSD) { printf ( "服务器%d.%d.%d.%d断开连接\r\n" , 192 , 168 , 8 , 2 ) ; vTaskSuspend ( client_rec_handle) ; } }
}