Сейчас я работаю с STM32F107 + lwip. Целью является создание шлюза, который будет использоваться для обмена данными между ETHERNET и CAN. UDP-сервер хорошо протестирован, и теперь я хочу усилить функцию TCP-сервера, которому можно разрешить установить 5 TCP-соединений.
Мои вопросы:
1 TCP-соединение протестировано нормально. Как реализовать 5 TCP-соединений?
Во-первых, ПК отправляет данные в STM32 через TCP-соединения. STM32 получает его и отправляет в CAN. Затем, когда STM32 получает данные от CAN, он отправляет данные на ПК по всем TCP-соединениям. Теперь я считаю, что typedef структуры , когда STM32 получил данные с ПК, он запишет плату, удаленный IP и удаленный порт. И, получив данные от CAN, STM32 отправит их через данные записи. В результате данные будут отправляться медленно, когда STM32 часто вызывает «tcp_write ()» и «tcp_output».
Так что мне интересно, какие решения для реализации нескольких TCP-соединений.
#define TCP_WORKING 0xaa
#define TCP_FREE 0xa5
typedef struct Cmd_TCPData
{
unsigned char TCP_STATUS;
unsigned char cmd_flag;
unsigned short remote_port;
unsigned short data_len;
struct ip_addr remote_ip;
unsigned char *pData;
struct tcp_pcb *TCP_pcb;
}Cmd_TCPData;
Cmd_TCPData cmd_tcp;
Cmd_TCPData tcp_list[5];
static u8 TcpListNum;
void TCP_server_init(void)
{
struct tcp_pcb *pcb;
err_t err;
/*****************************************************/
pcb = tcp_new();
if (!pcb)
{
return ;
}
err = tcp_bind(pcb,IP_ADDR_ANY,devInfo.udpPort);
if(err != ERR_OK)
{
return ;
}
pcb = tcp_listen(pcb);
tcp_accept(pcb,tcp_server_accept);
}
static err_t tcp_server_accept(void *arg,struct tcp_pcb *pcb,err_t err)
{
tcp_setprio(pcb, TCP_PRIO_MIN);
tcp_recv(pcb,tcp_server_recv);
err = ERR_OK;
return err;
}
static err_t tcp_server_recv(void *arg, struct tcp_pcb *pcb,struct pbuf *p,err_t err)
{
struct pbuf *p_temp = p;
int nPos=0;
u8 searchtemp=0;
//TCP_pcbA=pcb;
while(tcp_list[searchtemp].TCP_STATUS==TCP_WORKING)
{
if(tcp_list[searchtemp].remote_ip.addr!= pcb->remote_ip.addr)
{
searchtemp++;
}
else
break;
if(searchtemp==5)
{
searchtemp=0;
break;
}
}
/******copy*******************/
tcp_list[searchtemp].TCP_pcb=pcb;
tcp_list[searchtemp].pData = TCPRecvBuf;
tcp_list[searchtemp].remote_port=pcb->remote_port;
tcp_list[searchtemp].remote_ip = pcb->remote_ip;
tcp_setprio(tcp_list[searchtemp].TCP_pcb, TCP_PRIO_MIN+searchtemp);
if(p_temp != NULL)
{
tcp_recved(pcb, p_temp->tot_len);
while(p_temp != NULL)
{
// tcp_write(pcb,p_temp->payload,p_temp->len,TCP_WRITE_FLAG_COPY);
// tcp_output(pcb);
memcpy(tcp_list[searchtemp].pData+nPos,p_temp->payload,p_temp->len);
nPos += p_temp->len;
p_temp = p_temp->next;
}
}
else
{
tcp_close(pcb);
}
tcp_list[searchtemp].data_len = nPos;
flash_led_tcp = 1;
tcp_list[searchtemp].TCP_STATUS= TCP_WORKING;
TcpListNum=searchtemp;
pbuf_free(p);
err = ERR_OK;
return err;
}
void send_tcp_data(u8_t *pPtr,u16_t data_len)
{
u8 x=0;
while(x<5)
{
if(tcp_list[x].TCP_STATUS==TCP_WORKING)
{
//TCP_pcbA->remote_port=tcp_list[x].remote_port;
//TCP_pcbA->remote_ip= tcp_list[x].remote_ip;
tcp_write(tcp_list[x].TCP_pcb,pPtr,data_len,TCP_WRITE_FLAG_COPY);
tcp_output(tcp_list[x].TCP_pcb);
}
OSTimeDlyHMSM(0, 0, 0, 250);//250ms
x++;
}
}