You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
252 lines
4.9 KiB
252 lines
4.9 KiB
|
3 weeks ago
|
#include "tcp_server.h"
|
||
|
|
#include "lwip/tcp.h"
|
||
|
|
#include "lwip/memp.h"
|
||
|
|
#include <string.h>
|
||
|
|
#include "lwip.h"
|
||
|
|
|
||
|
|
#include "string.h"
|
||
|
|
#include "bsp_UDP.h"
|
||
|
|
#include "bsp_DLT_Log.h"
|
||
|
|
#include <bsp_UpperComputer_Handler.h>
|
||
|
|
#include "BSP/bsp_GPIO.h"
|
||
|
|
static client_conn_t clients[MAX_CLIENTS];
|
||
|
|
static struct tcp_pcb *server_pcb = NULL;
|
||
|
|
void send_tcp(SendDataNode **head);
|
||
|
|
// 回调函数声明
|
||
|
|
static err_t tcp_accept_cb(void *arg, struct tcp_pcb *newpcb, err_t err);
|
||
|
|
static err_t tcp_recv_cb(void *arg, struct tcp_pcb *tpcb, struct pbuf *p,
|
||
|
|
err_t err);
|
||
|
|
static void tcp_err_cb(void *arg, err_t err);
|
||
|
|
static void tcp_sent_cb(void *arg, struct tcp_pcb *tpcb, u16_t len);
|
||
|
|
SendDataNode *pTcpHead = NULL; /*初始化链表头指针,使其为空*/
|
||
|
|
void tcp_server_timer_callback();
|
||
|
|
char listIndex = 0;
|
||
|
|
SendDataNode* CreateSendDataNode(uint8_t *tx_Buf, uint8_t tx_count)
|
||
|
|
{
|
||
|
|
SendDataNode *newNode = (SendDataNode*) malloc(sizeof(SendDataNode));
|
||
|
|
if (newNode == NULL)
|
||
|
|
{
|
||
|
|
return NULL;
|
||
|
|
}
|
||
|
|
memcpy(newNode->Tx_Buf, tx_Buf, tx_count);
|
||
|
|
newNode->Tx_Count = tx_count;
|
||
|
|
newNode->next = NULL;
|
||
|
|
return newNode;
|
||
|
|
}
|
||
|
|
|
||
|
|
void insertAtTail(SendDataNode **head, uint8_t *tx_Buf, uint8_t tx_count)
|
||
|
|
{
|
||
|
|
SendDataNode *newNode = CreateSendDataNode(tx_Buf, tx_count);
|
||
|
|
// 如果链表为空
|
||
|
|
if (*head == NULL)
|
||
|
|
{
|
||
|
|
|
||
|
|
*head = newNode;
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
listIndex = 0;
|
||
|
|
// 遍历到链表尾部
|
||
|
|
SendDataNode *current = *head;
|
||
|
|
while (current->next != NULL)
|
||
|
|
{
|
||
|
|
// listIndex++;
|
||
|
|
// if (listIndex >= 50)
|
||
|
|
// {
|
||
|
|
// free(current);
|
||
|
|
// return;
|
||
|
|
// }
|
||
|
|
current = current->next;
|
||
|
|
}
|
||
|
|
//SendDataNode *newNode = CreateSendDataNode(tx_Buf, tx_count);
|
||
|
|
current->next = newNode; // 尾部节点指向新节点
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void tcp_add_sendList(uint8_t *tx_Buf, uint8_t tx_count)
|
||
|
|
{
|
||
|
|
|
||
|
|
for (int i = 0; i < MAX_CLIENTS; i++)
|
||
|
|
{
|
||
|
|
if (clients[i].active)
|
||
|
|
{
|
||
|
|
insertAtTail(&pTcpHead, tx_Buf, tx_count);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void send_tcp(SendDataNode **head)
|
||
|
|
{
|
||
|
|
if (*head == NULL)
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
tcp_send_to_all_clients((*head)->Tx_Buf, (*head)->Tx_Count);
|
||
|
|
SendDataNode *temp = *head;
|
||
|
|
*head = (*head)->next;
|
||
|
|
free(temp);
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
// 初始化TCP服务器
|
||
|
|
void tcp_server_init(uint16_t port)
|
||
|
|
{
|
||
|
|
GF_BSP_Interrupt_Add_CallBack(
|
||
|
|
DF_BSP_InterCall_TIM8_2ms_PeriodElapsedCallback,
|
||
|
|
tcp_server_timer_callback);
|
||
|
|
err_t err;
|
||
|
|
|
||
|
|
// 创建TCP控制块
|
||
|
|
server_pcb = tcp_new_ip_type(IPADDR_TYPE_ANY);
|
||
|
|
if (!server_pcb) return;
|
||
|
|
|
||
|
|
// 绑定到指定端口
|
||
|
|
err = tcp_bind(server_pcb, IP_ANY_TYPE, port);
|
||
|
|
if (err != ERR_OK)
|
||
|
|
{
|
||
|
|
memp_free(MEMP_TCP_PCB, server_pcb);
|
||
|
|
server_pcb = NULL;
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 开始监听
|
||
|
|
server_pcb = tcp_listen(server_pcb);
|
||
|
|
if (!server_pcb) return;
|
||
|
|
|
||
|
|
// 设置接受连接回调
|
||
|
|
tcp_accept(server_pcb, tcp_accept_cb);
|
||
|
|
|
||
|
|
// 初始化客户端数组
|
||
|
|
memset(clients, 0, sizeof(clients));
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
// 接受新连接回调
|
||
|
|
static err_t tcp_accept_cb(void *arg, struct tcp_pcb *newpcb, err_t err)
|
||
|
|
{
|
||
|
|
LWIP_UNUSED_ARG(arg);
|
||
|
|
LWIP_UNUSED_ARG(err);
|
||
|
|
|
||
|
|
// 查找空闲的客户端槽位
|
||
|
|
int free_index = -1;
|
||
|
|
for (int i = 0; i < MAX_CLIENTS; i++)
|
||
|
|
{
|
||
|
|
if (!clients[i].active)
|
||
|
|
{
|
||
|
|
free_index = i;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (free_index == -1)
|
||
|
|
{
|
||
|
|
// 没有可用槽位,拒绝连接
|
||
|
|
tcp_abort(newpcb);
|
||
|
|
return ERR_ABRT;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 配置新连接
|
||
|
|
tcp_setprio(newpcb, TCP_PRIO_MIN);
|
||
|
|
tcp_recv(newpcb, tcp_recv_cb);
|
||
|
|
tcp_err(newpcb, tcp_err_cb);
|
||
|
|
tcp_sent(newpcb, tcp_sent_cb);
|
||
|
|
|
||
|
|
// 保存客户端信息
|
||
|
|
clients[free_index].pcb = newpcb;
|
||
|
|
clients[free_index].active = 1;
|
||
|
|
|
||
|
|
return ERR_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 接收数据回调
|
||
|
|
static err_t tcp_recv_cb(void *arg, struct tcp_pcb *tpcb, struct pbuf *p,
|
||
|
|
err_t err)
|
||
|
|
{
|
||
|
|
LWIP_UNUSED_ARG(arg);
|
||
|
|
|
||
|
|
if (!p)
|
||
|
|
{
|
||
|
|
// 连接关闭
|
||
|
|
for (int i = 0; i < MAX_CLIENTS; i++)
|
||
|
|
{
|
||
|
|
if (clients[i].pcb == tpcb)
|
||
|
|
{
|
||
|
|
clients[i].active = 0;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
tcp_close(tpcb);
|
||
|
|
return ERR_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 处理接收到的数据(这里简单释放)
|
||
|
|
tcp_recved(tpcb, p->tot_len);
|
||
|
|
pbuf_free(p);
|
||
|
|
|
||
|
|
return ERR_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 错误回调
|
||
|
|
static void tcp_err_cb(void *arg, err_t err)
|
||
|
|
{
|
||
|
|
LWIP_UNUSED_ARG(err);
|
||
|
|
|
||
|
|
for (int i = 0; i < MAX_CLIENTS; i++)
|
||
|
|
{
|
||
|
|
if (clients[i].pcb == arg)
|
||
|
|
{
|
||
|
|
clients[i].active = 0;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 数据发送完成回调
|
||
|
|
static void tcp_sent_cb(void *arg, struct tcp_pcb *tpcb, u16_t len)
|
||
|
|
{
|
||
|
|
LWIP_UNUSED_ARG(arg);
|
||
|
|
LWIP_UNUSED_ARG(tpcb);
|
||
|
|
LWIP_UNUSED_ARG(len);
|
||
|
|
// 可在此实现流量控制
|
||
|
|
}
|
||
|
|
|
||
|
|
// 向所有活跃客户端发送数据
|
||
|
|
void tcp_send_to_all_clients(const char *data, uint16_t len)
|
||
|
|
{
|
||
|
|
for (int i = 0; i < MAX_CLIENTS; i++)
|
||
|
|
{
|
||
|
|
if (clients[i].active)
|
||
|
|
{
|
||
|
|
//clients[i].pcb->flags=
|
||
|
|
// err_t err = tcp_write(clients[i].pcb, data, len,
|
||
|
|
// TCP_WRITE_FLAG_COPY);
|
||
|
|
err_t err = tcp_write(clients[i].pcb, data, len,
|
||
|
|
TCP_WRITE_FLAG_COPY);
|
||
|
|
if (err == ERR_OK)
|
||
|
|
{
|
||
|
|
tcp_output(clients[i].pcb);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
// 发送失败,关闭连接
|
||
|
|
//clients[i].active = 0;
|
||
|
|
//tcp_close(clients[i].pcb);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
int32_t counter = 0;
|
||
|
|
// 定时器回调(从主定时器中断调用)
|
||
|
|
void tcp_server_timer_callback()
|
||
|
|
{
|
||
|
|
|
||
|
|
counter++;
|
||
|
|
if (counter > 5)
|
||
|
|
{
|
||
|
|
counter = 0;
|
||
|
|
send_tcp(&pTcpHead);
|
||
|
|
};
|
||
|
|
|
||
|
|
}
|
||
|
|
|