socket和shutdown

從函數調用上來分析(msdn):一旦完成了套接字的連接,應當將套接字關閉,並且釋放其套接字句柄所佔用的所有資源。真正釋放一個已經打開的套接字句柄的資源直接調用closesocket即可,但要明白closesocket的調用可能會帶來負面影響,具體的影響和如何調用有關,最明顯的影響是數據丟失,因此一般都要在closesocket之前調用shutdown來關閉套接字。  
          shutdown:爲了保證通信雙方都能夠收到應用程序發出的所有數據,一個合格的應用程序的做法是通知接受雙發都不在發送數據!這就是所謂的“正常關閉”套接字的方法,而這個方法就是由shutdown函數,傳遞給它的參數有SD_RECEIVE,SD_SEND,SD_BOTH三種,如果是SD_RECEIVE就表示不允許再對此套接字調用接受函數。這對於協議層沒有影響,另外對於tcp套接字來說,無論數據是在等候接受還是即將抵達,都要重置連接(注意對於udp協議來說,仍然接受並排列傳入的數據,因此udp套接字而言shutdown毫無意義)。如果選擇SE_SEND,則表示不允許再調用發送函數。對於tcp套接字來說,這意味着會在所有數據發送出並得到接受端確認產生一個FIN包。如果指定SD_BOTH,答案不言而喻。   
          closesocket:對此函數的調用會釋放套接字的描述,這個道理衆所周知(凡是經常翻閱msdn的程序員),因此,調用此函數,再是用此套接字就會發生調用失敗,通常返回的錯誤是WSAENOTSOCK。此時與被closesocket的套接字描述符相關聯的資源都會被釋放,包括丟棄傳輸隊列中的數據!!!!對於當前進程中的線程來講,所有被關起的操作,或者是被掛起的重疊操作以及與其關聯的任何事件,完成例程或完成端口的執行都將調用失敗!另外SO_LINGER標誌還影響着closesocket的行爲,但對於傳統的socket程序,這裏不加解釋   
          因此可以可以看出shutdown對切斷連接有着合理的完整性。   
          下面從tcp協議上來分析shutdown和closesocket的行爲(beha
vior):closesocket或shutdown(使用SD_SEND當作參數時),會向通信對方發出一個fin包,而此時套接字的狀態會由ESTABLISHED變成FIN_WAIT_1,然對方發送一個ACK包作爲迴應,套接字又變成FIN_WAIT_2,如果對方也關閉了連接則對方會發出FIN,我方會迴應一個ACK並將套接字置爲TIME_WAIT。因此可以看出closesocket,shutdown所進行的TCP行爲是一樣的,所不同的是函數部分,shutdown會確保windows建立的數據傳輸隊列中的數據不被丟失,而closesocket會冒然的拋棄所有的數據,因此如果你願意closesocket完全可以取代shutdown,然而在數據交互十分複雜的網絡協議程序中,最好還是shutdown穩妥一些!?
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章