首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

Beej's Guide 第 16 章:close() 與 shutdown() —— 優雅關閉套接字

     編輯:關於C

close():標準關閉


#include <unistd.h>
int close(int sockfd);
  • 減少文件描述符引用計數。計數歸零時,內核發送 FIN 包,進入 TCP 關閉流程 (FIN_WAIT -> TIME_WAIT)。
  • **雙向關閉**:後續 read()/recv() 返回 0 (EOF);write()/send() 觸發 SIGPIPE 或返回 EPIPE。
  • 適用於「不再收發」的簡單場景。

shutdown():定向關閉


#include <sys/socket.h>
int shutdown(int sockfd, int how);

how 取值:

值宏效果
0SHUT_RD**禁止接收**。接收緩衝區數據丟棄,後續 recv 返回 0。發送功能保留。
1SHUT_WR**禁止發送**。發送 FIN,後續 send 返回 EPIPE。接收功能保留 (可讀取對端剩餘數據)。
2SHUT_RDWR**雙向禁止**。等同 close() (但不釋放描述符,需後續 close() 釋放 fd)。

關鍵差異與用法

  1. 半關閉:shutdown(sockfd, SHUT_WR) 告訴對端「我發完了」,但我還能收。對端 recv 返回 0,知曉無新數據。這是**應用層協議結束標記**的標準做法 (如 HTTP 請求發送完畢)。
  2. 描述符生命週期:shutdown 不關閉文件描述符,select/epoll 仍可監聽該 fd (僅可讀事件)。必須最終調用 close() 釋放 fd。
  3. 數據報套接字: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) 是實現健壯網絡協議 (避免數據丟失、協議同步) 的關鍵技能。

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