首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Linux 內核 TCP 發送流程源碼深度解析:Socket 層篇

     編輯:Java 綜合教學

Linux 內核 TCP 發送流程源碼深度解析:Socket 層

基於 Linux 3.15.2 內核源碼,從用戶態 send() 系統調用入手,追蹤數據如何流經 Socket 層進入 TCP 協議棧。掌握此流程對網絡調優、零拷貝理解、內核旁路技術研發至關重要。

1. 核心數據結構關係圖

Socket 數據結構關係

  • struct socket:用戶態文件描述符對應的內核對象,持有 struct sock *sk 指向協議層對象。
  • struct sock:協議無關的核心對象,TCP 對應 struct tcp_sock。
  • struct proto_ops:Socket 操作函數表,inet_stream_ops.sendmsg = inet_sendmsg。

2. 發送流程總覽

發送流程圖

write/send/sendto/sendmsg/sendmmsg 系統調用差異僅在參數組裝,最終均匯聚至 sock_sendmsg() → inet_sendmsg() → tcp_sendmsg()。

3. 用戶態 API 與 msghdr

// 消息頭:描述分散/聚集 I/O、目標地址、控制數據
struct msghdr {
    void *msg_name;        // 目標地址 (sendto 用)
    socklen_t msg_namelen;
    struct iovec *msg_iov; // 數據塊數組 (scatter/gather)
    size_t msg_iovlen;     // 數據塊個數
    void *msg_control;     // 輔助數據 (如文件描述符傳遞)
    socklen_t msg_controllen;
    int msg_flags;
};

struct iovec {
    void *iov_base; // 數據指針
    size_t iov_len; // 數據長度
};

阻塞/非阻塞由 O_NONBLOCK 或 MSG_DONTWAIT 控制。

4. 系統調用入口:sys_socketcall

所有 Socket 系統調用統一入口 sys_socketcall(int call, unsigned long *args),根據 call 分發:

case SYS_SEND:      return sys_send(a0, a1, a2, a3);
case SYS_SENDTO:    return sys_sendto(a0, a1, a2, a3, a4, a5);
case SYS_SENDMSG:   return sys_sendmsg(a0, a1, a2);
case SYS_SENDMMSG:  return sys_sendmmsg(a0, a1, a2, a3);

5. 關鍵內核函數調用鏈

  1. sys_sendto():組裝 msghdr,拷貝用戶態地址/數據,調用 sock_sendmsg()。
  2. sock_sendmsg():初始化 kiocb (AIO 控制塊),調用 __sock_sendmsg()。
  3. __sock_sendmsg_nosec():填充 sock_iocb,調用 sock->ops->sendmsg() 即 inet_sendmsg()。
  4. inet_sendmsg():
     a. 自動綁定端口(若未綁定且允許)。
     b. 調用 sk->sk_prot->sendmsg() 即 tcp_sendmsg() 進入 TCP 層。

6. 函數調用與數據結構關係圖

調用關係圖

7. 關鍵結構體定義

// AIO 控制塊
struct kiocb {
    struct file *ki_filp;
    struct kioctx *ki_ctx;      // 同步操作時為 NULL
    void *private;              // 指向 sock_iocb
    struct task_struct *tsk;    // 執行 I/O 的進程
    // ...
};

// Socket 專用 AIO 信息
struct sock_iocb {
    struct socket *sock;
    struct msghdr *msg;
    size_t size;
    // ...
};

下一篇預告

將深入 TCP 層 tcp_sendmsg():發送緩衝區管理、MSS 計算、Nagle 算法、零拷貝 sendfile/splice 實現、拥塞控制入口等。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved