STM32运行LwIP协议时,如何实现5个TCP连接?

时间:2017-06-29 07:11:22

标签: tcp stm32 lwip

现在,我正在使用STM32F107 + lwip。目的是建立一个网关,用于在以太网和CAN之间交换数据。 UDP服务器测试得很好。现在我想增加TCP服务器功能,可以允许建立5个TCP连接。


我的问题:
 1 TCP连接测试好了,如何实现5个TCP连接?


首先,PC通过TCP连接向STM32发送数据。 STM32接收它并将其发送到CAN。然后,当STM32从CAN接收数据时,它将通过所有TCP连接将数据发送到PC。现在,我的想法是typedef结构,当STM32从PC接收数据时,它将记录pcb,远程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++;
    }   
}

1 个答案:

答案 0 :(得分:0)

tcp_server_accept()将包含新创建的连接。对于此连接,您可以附加您的上下文。

struct myclient_t
{
    struct tcp_pcb *pcb;
    /* all the variables uniqe for tracking this specific connection.. parser-state, receive/send buffers, statistics... */
    int foo;
    int bar;
};

static err_t tcp_server_accept(void *arg,struct tcp_pcb *pcb,err_t err)
{
    err_t ret_err;
    struct struct myclient_t *context = 0;
    int i;

    context = new_client();
    if (!context )
    {
        return ERR_MEM;
    }

    context->pcb = pcb;

    /* pass newly allocated es structure as argument to newpcb */
    tcp_arg(newpcb, context); /* recv, sent, error and poll callbacks will have context their argument, which is uniqe for each connection */

    /* initialize lwip tcp_recv callback function for newpcb  */ 
    tcp_recv(newpcb, tcp_server_recv

    tcp_sent(newpcb, tcp_server_sent);

    /* initialize lwip tcp_err callback function for newpcb  */
    tcp_err(newpcb, tcp_server_error);

    /* initialize lwip tcp_poll callback function for newpcb */
    tcp_poll(newpcb, tcp_server_poll, 1);

    return ERR_OK;
}