3 回答

TA貢獻1836條經驗 獲得超3個贊
一、指代不同
1、shutdown() :是指禁止在一個套接口上進行數據的接收與發送。
2、close():關閉一個套接口。更確切地說,它釋放套接口描述字s,以后對s的訪問均以WSAENOTSOCK錯誤返回。
二、原理不同
1、shutdown() :how參數為0,則該套接口上的后續接收操作將被禁止。這對于低層協議無影響。對于TCP協議,TCP窗口不改變并接收前來的數據(但不確認)直至窗口滿。對于UDP協議,接收并排隊前來的數據。任何情況下都不會產生ICMP錯誤包。
2、close():為對套接口的最后一次訪問,則相應的名字信息及數據隊列都將被釋放。closesocket()的語義受SO_LINGER與SO_DONTLINGER選項影響。
三、特點不同
1、shutdown() :一個應用程序不應依賴于重用一個已被shutdown()禁止的套接口。特別地,一個WINDOWS套接口實現不必支持在這樣的套接口上使用connect()調用。
2、close():如無錯誤發生,則closesocket()返回0。否則的話,返回SOCKET_ERROR錯誤,應用程序可通過WSAGetLastError()獲取相應錯誤代碼。

TA貢獻1829條經驗 獲得超7個贊
下面說說close和shutdown兩個函數的差別,兩個函數在網絡編程中都被人為是來關閉套接字的,差別如下:
1.操作本質不同
close是文件系統VFS的一個通用函數
shutdown是專門針對socket套接字設立的函數
SOCKET在unix中本就是以文件的形式呈現給大家的,在每創建一個socket時,會對應創建一個文件與之對應,返回文件描述符,
具體的結構在此不詳述,在調用close時實際是關閉了減少了文件描述符,當文件描述符引用為0時,則會刪除文件,關閉套接字。
而shutdown是直接對socket的操作,相當于設置了socket的屬性,可以設置為只讀,只寫,或者直接關閉,但不會操作與此socket相關
的文件
2.兩者操作的效果一同
close的操作跟設置選項LINGER有關,此選項是設置當用戶調用close后是否等待把當前緩沖區的數據發送完畢后再關閉套接字
LINGER結構有兩個值,一個是on,一個是time
當on為0時,默認情況,用戶發送完分組,然后發送FIN分組
當on為1時,time為0,則用戶直接發送RST分組
當on為1時,time為非0,則用戶等待time值然后發送FIN分組,如果time到了但用戶沒有發送完數據,則返回錯誤EWOULDBLOCK
SHUTDOWN
SHUT_RD,套接字不能再發出接收請求,進程仍然可以往套接字發送數據,套接字接收緩沖區中所有數據被丟棄,再接收到的任何數據由TCP丟棄,對套接字發送緩沖區沒有任何影響
SHUT_WD ,套接字不能再發出發送請求,套接字發送緩沖區的數據將被發送到對端,然后跟著正常的FIN終止序列

TA貢獻1841條經驗 獲得超3個贊
當所有的數據操作結束以后,你可以調用close()函數來釋放該socket,從而停止在該socket上的任何數據操作:close(sockfd);
你也可以調用shutdown()函數來關閉該socket。但是該函數允許你只停止在某個方向上的數據傳輸,而一個方向上的數據傳輸繼續進行。如你可以關 閉某socket的寫操作而允許繼續在該socket上接受數據,直至讀入所有數據。
int shutdown(int sockfd,int how);
Sockfd是需要關閉的socket的描述符。參數 how允許為shutdown操作選擇以下幾種方式:
SHUT_RD:關閉連接的讀端。也就是該套接字不再接受數據,任何當前在套接字接受緩沖區的數據將被丟棄。進程將不能對該套接字發出任何讀操作。對 TCP套接字該調用之后接受到的任何數據將被確認然后無聲的丟棄掉。
SHUT_WR:關閉連接的寫端,進程不能在對此套接字發出寫操作
SHUT_RDWR:相當于調用shutdown兩次:首先是以SHUT_RD,然后以SHUT_WR
使用close中止一 個連接,但它只是減少描述符的參考數,并不直接關閉連接,只有當描述符的參考數為0時才關閉連接。
shutdown可直接關閉描述符,不考慮描述 符的參考數,可選擇中止一個方向的連接。
注意:
1>. 如果有多個進程共享一個套接字,close每被調用一次,計數減1,直到計數為0時,也就是所用進程都調用了close,套接字將被釋放。
2>. 在多進程中如果一個進程中shutdown(sfd, SHUT_RDWR)后其它的進程將無法進行通信. 如果一個進程close(sfd)將不會影響到其它進程. 得自己理解引用計數的用法了
- 3 回答
- 0 關注
- 413 瀏覽
添加回答
舉報