Q:SylixOS TCP 数据段发送流程简述
1、在 LwIP 协议栈中使用 TCP 控制块结构 struct tcp_pcb 管理 TCP 连接,使用 TCP 段结构 struct tcp_seg 描述 TCP 段。在 TCP 控制块中有两个队列 unsent 与 unacked 表示所有未发送的 TCP 数据段和发送了还未收到确认的 TCP 数据段。如下图所示。
2、TCP 连接发送数据由应用层发起,数据段构建后首先被缓存在 TCP 控制块的 unsent 链表中,随后调用网卡驱动发送接口发送数据,流程如下:
1)调用 write 发送 TCP 数据。write 接口最终会调用 LwIP TCP 发送函数 tcp_write() 调用链如下:
write() ---> __socketWrite() ---> lwip_write() ---> lwip_send() ---> netconn_write_partly() ---> netconn_write_vectors_partly() ---> lwip_netconn_do_write() ---> lwip_netconn_do_writemore() ---> tcp_write()
2)在 tcp_write() 中会构建新的 TCP 段,且大部分 TCP 协议内容在这里完成,新构建的 TCP 段会被放入 pcb->unsend 队列中;
3)调用 tcp_output() 用于发送 TCP 段。在 tcp_output() 中首先通过 tcp_route() 获取发送网卡结构 netif,将 unsend、unacked 队列中的 TCP 段通过 tcp_output_segment() 提交到 IP 层。在 tcp_input()、tcp_close()、tcp_connect() 等函数中也会调用 tcp_output() 用于实现 TCP 链接各个过程中的报文发送;
4)IP 层最终调用到网卡驱动发送接口,函数调用流程如下:
tcp_output_segment() ---> ip_output_if() ---> ip4_output_if() ---> ip4_output_if_opt_src() (大部分 IP 层协议内容在这里完成) ---> ethernet_output() ---> netdev_netif_linkoutput() ---> NETDEV_TRANSMIT()