Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> Linux 教學

Linux 進階 Socket 函數:recv、send、recvmsg、sendmsg 與 shutdown 詳解

編輯:Linux 教學

一、recv / send:帶旗標的資料收發

ssize_t recv(int sockfd, void *buf, size_t len, int flags);
ssize_t send(int sockfd, const void *buf, size_t len, int flags);

前三參數同 read/write,第四參數 flags 控制行為(可組合):

旗標適用函數語意
MSG_DONTROUTEsend繞過路由表,直接送往本地網段(診斷/路由器用)
MSG_OOBrecv/send收發帶外資料(TCP 緊急指標)
MSG_PEEKrecv窺視緩衝區資料,不移除(多進程協同讀取)
MSG_WAITALLrecv阻塞直到收滿 len 位元組、遇 EOF 或發生錯誤

flags=0 時行為等同 read/write。

二、recvfrom / sendto:無連線 Socket 專用

已於前文詳細說明,此處不贅述。適用於 SOCK_DGRAM (UDP) 及 SOCK_RAW。

三、recvmsg / sendmsg:通用訊息介面

可一次處理多個分散緩衝區(scatter/gather I/O)與控制資料(如檔案描述符傳遞、IP 選項)。

struct msghdr {
    void         *msg_name;       // 目的/來源位址 (SOCK_DRAM 用)
    socklen_t     msg_namelen;
    struct iovec *msg_iov;        // 分散緩衝區陣列
    int           msg_iovlen;     // 陣列長度
    void         *msg_control;    // 控制資料 (cmsg)
    socklen_t     msg_controllen;
    int           msg_flags;      // 回傳旗標 (MSG_EOR, MSG_TRUNC 等)
};

struct iovec {
    void  *iov_base;  // 緩衝區起始位址
    size_t iov_len;   // 緩衝區長度
};
  • 面向連線 Socket:msg_name 設 NULL。
  • 控制資料用於傳遞檔案描述符 (SCM_RIGHTS)、IP TTL/選項等進階功能。

四、Socket 關閉機制:close vs shutdown

int close(int fd);           // 參考計數-1,歸零時關閉雙向通道
int shutdown(int sockfd, int how);

shutdown 參數 how:

  • SHUT_RD (0):關閉讀端,接收緩衝區資料丟棄,後續 recv 返回 0 (EOF)。
  • SHUT_WR (1):關閉寫端,發送 FIN 包,後續 send 觸發 SIGPIPE。
  • SHUT_RDWR (2):雙向關閉,等同 close 但不受參考計數影響。

多進程共享 Socket 時的關鍵差異

  • close:僅減少當前進程的檔案描述符參考計數,其他進程仍可繼續使用該 Socket。
  • shutdown:直接作用於 Socket 核心結構,**所有共享該 Socket 的進程** 皆受影響,無法再收發。

因此,父進程 fork 子進程後,若需各自獨立關閉連線,應使用 close;若需協同終止通訊(如伺服器優雅關閉),則在最後一個進程呼叫 shutdown(SHUT_WR) 發送 FIN,再各自 close。

Copyright © Windows教程網 All Rights Reserved