c
复制代码
//
// Created by shchl on 2024/3/8.
//
#if 1
#include <string.h>
#include "lwip/api.h"
#include "FreeRTOS.h"
#include "task.h"
#include "usart.h"
#include "lwip_comm.h"
static TaskHandle_t tcp_server; /*任务句柄*/
static void tcp_server_entity(void *args);
void netconn_tcp_server_create_thread() {
xTaskCreate(
(TaskFunction_t) tcp_server_entity,
"tcp_server",
256,
NULL,
10,
&tcp_server
);
}
#define TCP_SERVER_RX_BUFSIZE 1500
static struct netconn *conn;
static struct netconn *client_conn;/*客户端连接*/
static uint8_t remot_addr[4] = {0}; /*远端ip数组*/
static u16_t port;/*远端端口*/
static ip_addr_t ipaddr;/*远端ip*/
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); //创建一个TCP链接
netconn_bind(conn, IP_ADDR_ANY, 8080); //绑定端口 8号端口
netconn_listen(conn); //进入监听模式
conn->recv_timeout = 10; //禁止阻塞线程 等待10ms
struct netbuf *recvbuf;
u32_t data_len = 0;
while (1) {
handle_listen_tag:
err = netconn_accept(conn, &client_conn); //接收连接请求
if (err == ERR_OK) {
client_conn->recv_timeout = 10;
netconn_getaddr(client_conn, &ipaddr, &port, 0); //获取远端IP地址和端口号
remot_addr[3] = (uint8_t) (ipaddr.addr >> 24);
remot_addr[2] = (uint8_t) (ipaddr.addr >> 16);
remot_addr[1] = (uint8_t) (ipaddr.addr >> 8);
remot_addr[0] = (uint8_t) (ipaddr.addr);
printf("主机%d.%d.%d.%d连接上服务器,主机端口号为:%d\r\n",
remot_addr[0], remot_addr[1], remot_addr[2], remot_addr[3], port);
handle_client_tag:/*处理客户端请求*/
err = netconn_recv(client_conn, &recvbuf);
switch (err) {
case ERR_OK: {
portDISABLE_INTERRUPTS();
memset(tcp_server_recvbuf, 0, TCP_SERVER_RX_BUFSIZE); //数据接收缓冲区清零
for (struct pbuf *q = recvbuf->p; q != NULL; q = q->next) //遍历完整个pbuf链表
{
if (q->len > (TCP_SERVER_RX_BUFSIZE - data_len)) {
/*数据超出缓冲区大小*/
memcpy(tcp_server_recvbuf + data_len, q->payload, TCP_SERVER_RX_BUFSIZE - data_len);
break;
} else {
memcpy(tcp_server_recvbuf + data_len, q->payload, q->len);
}
data_len += q->len;
if (data_len > TCP_SERVER_RX_BUFSIZE) break;
}
portENABLE_INTERRUPTS();
// todo 应用逻辑处理
USART1_Transmits(tcp_server_recvbuf, data_len);
data_len = 0; //复制完成后data_len要清零。
netbuf_delete(recvbuf);
break;
}
case ERR_CLSD:
case ERR_RST: {
printf("主机:%d.%d.%d.%d断开与服务器的连接\r\n", remot_addr[0], remot_addr[1], remot_addr[2],
remot_addr[3]);
goto release_conn_tag;
}
default:
if (g_lwipdev.link_status == LWIP_LINK_OFF) { /*判断网线是否连接正常*/
printf("物理连线出现问题\r\n");
goto release_conn_tag;
}
break;
}
goto handle_client_tag;
release_conn_tag: /*释放链接*/
{
netconn_close(client_conn);
netconn_delete(client_conn);
goto handle_listen_tag;
}
}
vTaskDelay(1000);
}
}
#endif