Lwip使用RAW进行TCP 服务器的数据收发时主要流程如下:
1 tcp_new创建资源
tcp_server_pcb?= tcp_new();
2 tcp_bind绑定信息
tcp_bind(*tcp_server_pcb, ipaddr, port);
3 tcp_listen监听是否有客户端连接
*tcp_server_pcb = tcp_listen(*tcp_server_pcb);
注意这里listen的参数和返回值是一样的,因为tcp_listen这个函数会申请新的资源并释放原来的资源。函数调用顺序和源码如下:
tcp_listen————>tcp_listen_with_backlog————>
tcp_listen_with_backlog_and_err
tcp_listen_with_backlog_and_err(struct?tcp_pcb *pcb,?u8_t?backlog,?err_t?*err)
{
? ...
? ...
? lpcb = (struct?tcp_pcb_listen *)memp_malloc(MEMP_TCP_PCB_LISTEN);
? ...
? ...
??tcp_free(pcb);
? ...
? ...
??return?(struct?tcp_pcb *)lpcb;
}
程序先申请了新的内存(memp_malloc),并释放了原来的资源(tcp_free),并将新的返回(return?(struct?tcp_pcb *)lpcb)。4 tcp_accept
tcp_accept(*tcp_server_pcb, tcp_severXXX_accept)
有客户端连接后会调用tcp_serverXXX_accept函数,在这个函数里注册之后的处理函数包括:
注册参数函数tcp_arg注册接收回调函数tcp_recv注册错误回调函数tcp_err注册轮询函数tcp_poll注册发送回调函数tcp_poll同时在这里获取客户端的资源块:
struct?tcp_pcb?*tcp_server_pcb_send;
err_t?tcp_severXXX_accept(void?*arg,?struct?tcp_pcb *pcb,?err_t?err)
{
? tcp_server_pcb_send = pcb;
??
??tcp_arg(pcb,&tcp_server0);
??tcp_recv(pcb,TCPServerCallback); ?//初始化tcp_recv()的回调函数
??tcp_err(pcb,tcp_server_error); ?//初始化tcp_err()回调函数
??tcp_poll(pcb,tcp_server_poll,1); ?//初始化tcp_poll回调函数
// ?tcp_sent(pcb,tcp_server_sent); ? //初始化发送回调函数
??return?ERR_OK; ? ??
}
这样就获取了连接的客户端资源块,可独立使用。
tcp_write(tcp_server_pcb0_send, sendbufferXXX, lengthXXX, XXX);
这样就可在别的函数中独立发送数据给客户端。单独调用函数tcp_server_send_data就可以。
void?tcp_server_send_data(struct?tcp_pcb *tpcb,uint8_t?*sendbuffer,uint32_t?length)?
{?
? ??tcp_write(tpcb, sendbuffer, length,?1);
? ??tcp_output(tpcb);
}?
阅读全文