#include <unistd.h>
int close(int sockfd);
FIN 包,進入 TCP 關閉流程 (FIN_WAIT -> TIME_WAIT)。read()/recv() 返回 0 (EOF);write()/send() 觸發 SIGPIPE 或返回 EPIPE。
#include <sys/socket.h>
int shutdown(int sockfd, int how);
how 取值:
| 值 | 宏 | 效果 |
|---|---|---|
| 0 | SHUT_RD | **禁止接收**。接收緩衝區數據丟棄,後續 recv 返回 0。發送功能保留。 |
| 1 | SHUT_WR | **禁止發送**。發送 FIN,後續 send 返回 EPIPE。接收功能保留 (可讀取對端剩餘數據)。 |
| 2 | SHUT_RDWR | **雙向禁止**。等同 close() (但不釋放描述符,需後續 close() 釋放 fd)。 |
shutdown(sockfd, SHUT_WR) 告訴對端「我發完了」,但我還能收。對端 recv 返回 0,知曉無新數據。這是**應用層協議結束標記**的標準做法 (如 HTTP 請求發送完畢)。shutdown 不關閉文件描述符,select/epoll 仍可監聽該 fd (僅可讀事件)。必須最終調用 close() 釋放 fd。shutdown 僅禁用 send/recv,不發送 FIN (UDP 無連接)。0:成功。-1:失敗,設置 errno。
// 發送端:發送完畢 -> 半關閉寫端 -> 可選讀取對端響應 -> 完全關閉
send(sockfd, data, len, 0);
shutdown(sockfd, SHUT_WR); // 發 FIN
char buf[1024];
while (recv(sockfd, buf, sizeof(buf), 0) > 0) { /* 處理對端最後響應 */ }
close(sockfd); // 釋放 fd
close() 是「斬草除根」,shutdown() 是「精準手術刀」。掌握半關閉 (SHUT_WR) 是實現健壯網絡協議 (避免數據丟失、協議同步) 的關鍵技能。