0
点赞
收藏
分享

微信扫一扫

45 | 发送网络包(上)

何以至千里 2021-09-25 阅读 25
  • 我们通过 VFS 中的 struct file,将创建好的 socket 结构拿出来,然后调用 sock_sendmsg>sock_sendmsg_nosec>(socket->ops>inet_stream_ops)> sock>(sk_prot->sendmsg )>tcp_sendmsg。其中走过的结构包括 VFS 找到Socket 然后通过它的private_date 得到 sock 再调用 它的 sk_port。
  • tcp_sendmsg 详解:
    • 第一步:tcp_write_queue_tail 从 TCP 写入队列 sk_write_queue 中拿出最后一个 struct sk_buff,因为可能上次用户给的数据太少,而没有填满。
    • 第二步:tcp_send_mss 会计算 MSS,也即 Max Segment Size。即传输网络包的最大带下。
    • 第三步:如果 copy 小于 0,说明最后一个 struct sk_buff 已经没地方存放了,需要调用 sk_stream_alloc_skb,重新分配 struct sk_buff,然后调用 skb_entail,将新分配的 sk_buff 放到队列尾部。
  • 第四步: 根据上述的聚合情况不同,要么 skb_add_data_nocache 将数据拷贝到连续的数据区域。要么 skb_copy_to_page_nocache 将数据拷贝到 struct skb_shared_info 结构指向的不需要连续的页面区域。

  • 第五步:就是要发生网络包了。第一种情况是积累的数据报数目太多了,因而我们需要通过调用 __tcp_push_pending_frames 发送网络包。第二种情况是,这是第一个网络包,需要马上发送,调用 tcp_push_one。无论 __tcp_push_pending_frames 还是 tcp_push_one,都会调用 tcp_write_xmit 发送网络包。

  • tcp_write_xmit 详解:

  • tcp_transmit_skb 发送真正的网络包:

举报

相关推荐

0 条评论