shutdown()

shutdown()是指禁止在一個套接口上進行數據的接收與傳送。

基本介紹

  • 外文名:shutdown()
  • 系統:linux/Windows
  • 支持協定:UDP/TCP
  • API類型:網路套接口
簡述,注釋,評註,

簡述

禁止在一個套接口上進行數據的接收與傳送。
s:用於標識一個套接口的描述字。
how:標誌,用於描述禁止哪些操作。
Linux:
#include<sys/socket.h>
int shutdown(int sockfd,int how);
linux下成功則返回0,錯誤返回-1,錯誤碼errno:EBADF表示sockfd不是一個有效描述符;ENOTCONN表示sockfd未連線;ENOTSOCK表示sockfd是一個描述符而不是socket描述符。
how的方式有三種分別是
SHUT_RD(0):關閉sockfd上的讀功能,此選項將不允許sockfd進行讀操作。
SHUT_WR(1):關閉sockfd的寫功能,此選項將不允許sockfd進行寫操作。
SHUT_RDWR(2):關閉sockfd的讀寫功能。
Windows:
#include <winsock.h>或#include <winsock2.h>
int PASCAL FAR shutdown( SOCKET s, int how);
how的方式有三種分別是
SD_RECEIVE(0):Shutdown receive operations.
SD_SEND(1):Shutdown send operations.
SD_BOTH(2):Shutdown both send and receive operations.

注釋

shutdown()函式用於任何類型的套接口禁止接收、禁止傳送或禁止收發。
如果how參數為0,則該套接口上的後續接收操作將被禁止。這對於低層協定無影響。對於TCP協定,TCP視窗不改變並接收前來的數據(但不確認)直至視窗滿。對於UDP協定,接收並排隊前來的數據。任何情況下都不會產生ICMP錯誤包。
若how為1,則禁止後續傳送操作。對於TCP,將傳送FIN。
若how為2,則同時禁止收和發。
請注意shutdown()函式並不關閉套接口,且套接口所占有的資源將被一直保持到closesocket()調用。

評註

無論SO_LINGER設定與否,shutdown()函式不會阻塞。
一個應用程式不應依賴於重用一個已被shutdown()禁止的套接口。特別地,一個WINDOWS套接口實現不必支持在這樣的套接口上使用connect()調用。
返回值:
如果沒有錯誤發生,shutdown()返回0。否則的話,返回SOCKET_ERROR錯誤,應用程式可通過WSAGetLastError()獲取相應錯誤代碼
錯誤代碼:
WSANOTINITIALISED:在使用此API之前應首先成功地調用WSAStartup()。
WSAENETDOWN:WINDOWS套接口實現檢測到網路子系統失效。
WSAEINVAL:how參數非法
WSAEINPROGRESS:一個阻塞的WINDOWS套接口調用正在運行中。
WSAENOTCONN:套接口未連線(僅適用於SOCK_STREAM類型套接口)。
WSAENOTSOCK:描述字不是一個套接口。
擴展知識:
Socket的close與shutdown
close-----關閉本進程的socket id,但連結還是開著的,用這個socket id的其它進程還能用這個連結,能讀或寫這個socket id。
shutdown--則破壞了socket 連結,讀的時候可能偵探到EOF結束符,寫的時候可能會收到一個SIGPIPE信號,這個信號可能直到socket buffer被填充了才收到。
更多關於close和shutdown的說明:
1. 如果有多個進程共享一個套接字,close每被調用一次,計數減1,直到計數為0時,也就是所用進程都調用了close,套接字將被釋放。
2. 在多進程中如果一個進程中shutdown(sfd, SHUT_RDWR)後其它的進程將無法進行通信. 如果一個進程close(sfd)將不會影響到其它進程. 得自己理解引用計數的用法了. 有Kernel編程知識的更好理解了.
3. 只要TCP棧的讀緩衝里還有未讀取(read)數據,則調用close時會直接向對端傳送RST。
4. shutdown與socket描述符沒有關係,即使調用shutdown(fd, SHUT_RDWR)也不會關閉fd,最終還需close(fd)。
5. 可以認為shutdown(fd, SHUT_RD)是空操作,因為shutdown後還可以繼續從該socket讀取數據,這點也許還需要進一步證實。
6. 在已傳送FIN包後write該socket描述符會引發EPIPE/SIGPIPE。
7. 當有多個socket描述符指向同一socket對象時,調用close時首先會遞減該對象的引用計數,計數為0時才會傳送FIN包結束TCP連線。shutdown不同,只要以SHUT_WR/SHUT_RDWR方式調用即傳送FIN包。
8. SO_LINGER與close,當SO_LINGER選項開啟但逾時值為0時,調用close直接傳送RST(這樣可以避免進入TIME_WAIT狀態,但破壞了TCP協定的正常工作方式),SO_LINGER對shutdown無影響。
9. TCP連線上出現RST與隨後可能的TIME_WAIT狀態沒有直接關係,主動發FIN包方必然會進入TIME_WAIT狀態,除非不傳送FIN而直接以傳送RST結束連線。
參見:
connect(), socket(),bind()

相關詞條

熱門詞條

聯絡我們