LWIP一个很大优势在于支持标准socket应用,完全可以屏蔽底层的交互过程,给使用带来的很多方便。今天以socket创建、连接、收发过程为例,分析下
socket层与协议栈层的数据交互过程。
(1) socket创建
APP层
Socket -> lwip_socket-> (SOCK_STREAM) netconn_new_with_callback(NETCONN_TCP)->
tcpip_apimsg -> (msg.type=TCPIP_MSG_API, msg.function = do_newconn) 发送一个消息并等待
TCP/IP协议栈层
通过tcpip_thread -> sys_mbox_fetch -> case TCPIP_MSG_API:msg.function = do_newconn -> pcb_new(NETCONN_TCP) -> tcp_new() -> tcp_alloc() ->
pcb=memp_malloc() -> pcb初始化-> return
(2)socket connect过程
数据处理流程:
APP 层
connect -> lwip_connect-> netconn_connect-> tcpip_apimsg(&msg)( msg.type = TCPIP_MSG_API, msg.function = do_connect) ->
sys_mbox_post(mbox, &msg);
TCP/IP协议栈层
通过
tcpip_thread->sys_mbox_fetch->case TCPIP_MSG_API: do_connect-> setup_tcp(setup recv_tcp、sent_tcp、poll_tcp and err_tcp)->tcp_connect(setup
paramters)-> tcp_enqueue(Enqueue data for transmission)-> tcp_output-> tcp_output_segment->ip_output->ip_output_if->(netif->output)->
etharp_output-> etharp_send_ip ->(netif->linkoutput)-> low_level_output. 自动处理握手过程
建立好连接后,进行数据的收发,下图比较清晰的看出数据的流动过程:
(3)数据recv接收流程:
TCP/IP协议栈层
ethernetif_input-> low_level_input-> (s_pxNetIf->input)-> tcpip_input-> sys_mbox_trypost
(msg->type = TCPIP_MSG_INPKT)-> tcpip_thread->sys_mbox_fetch-> case TCPIP_MSG_INPKT:(1 or 2)
1. ethernet_input(ARP包处理)-> etharp_arp_input->update_arp_entry(ARP_REQUEST->setup arp reply -> netif->linkoutput) or (ARP_REPLY-> updated
the ARP cache)
2. ip_input-> tcp_input(到pcb链表中去查询各个pcb的相关操作,处理应该回复的数据,根据内容调用TCP_EVENT_ERR、TCP_EVENT_RECV-
> sys_mbox_trypost发送邮箱给APP层)
APP 层
Connect调用返回。
(4)数据send流程
APP 层
Send->lwip_send->netconn_write-> (msg.type=TCPIP_MSG_API, msg.function = do_write)
发送消息
TCP/IP协议栈层
通过
tcpip_thread->sys_mbox_fetch->case TCPIP_MSG_API: do_write->do_writemore( see if has more data to be sent)->tcp_write->将待写数据放入
tcp_enqueue并填充各个数据段,完成数据包->tcp_output->tcp_output_segment->ip_output->ip_output_if->(netif->output)->
etharp_output->etharp_send_ip ->(netif->linkoutput)-> low_level_output
通过今天的分析,把LWIP数据流动过程进行了整理,在吃透一个协议栈之前这样做是必须的,再进行接下来的深入学习。