呼叫 close()/closesocket() 函式意味著完全斷開連線,即不能傳送資料也不能接收資料,這種「生硬」的方式有時候會顯得不太「優雅」。
上圖演示了兩台正在進行雙向通訊的主機。主機a傳送完資料後,單方面呼叫 close()/closesocket() 斷開連線,之後主機a、b都不能再接受對方傳輸的資料。實際上,是完全無法呼叫與資料收發有關的函式。
一般情況下這不會有問題,但有些特殊時刻,需要只斷開一條資料傳輸通道,而保留另一條。
使用 shutdown() 函式可以達到這個目的,它的原型為:
int shutdown(int sock, int howto); //linux
int shutdown(socket s, int howto); //windows
sock 為需要斷開的套接字,howto 為斷開方式。
howto 在 linux 下有以下取值:
shut_wr:斷開輸出流。套接字無法傳送資料,但如果輸出緩衝區中還有未傳輸的資料,則將傳遞到目標主機。
shut_rdwr:同時斷開 i/o 流。相當於分兩次呼叫 shutdown(),其中一次以 shut_rd 為引數,另一次以 shut_wr 為引數。
howto 在 windows 下有以下取值:
至於什麼時候需要呼叫 shutdown() 函式,下節我們會以檔案傳輸為例進行講解。
close()/closesocket()和shutdown()的區別
確切地說,close() / closesocket() 用來關閉套接字,將套接字描述符(或控制代碼)從記憶體清除,之後再也不能使用該套接字,與c語言中的 fclose() 類似。應用程式關閉套接字後,與該套接字相關的連線和快取也失去了意義,tcp協議會自動觸發關閉連線的操作。shutdown() 用來關閉連線,而不是套接字,不管呼叫多少次 shutdown(),套接字依然存在,直到呼叫 close() / closesocket() 將套接字從記憶體清除。
呼叫 close()/closesocket() 關閉套接字時,或呼叫 shutdown() 關閉輸出流時,都會向對方傳送 fin 包。fin 包表示資料傳輸完畢,計算機收到 fin 包就知道不會再有資料傳送過來了。
預設情況下,close()/closesocket() 會立即向網路中傳送fin包,不管輸出緩衝區中是否還有資料,而shutdown() 會等輸出緩衝區中的資料傳輸完畢再傳送fin包。也就意味著,呼叫 close()/closesocket() 將丟失輸出緩衝區中的資料,而呼叫 shutdown() 不會。
優雅的斷開連線 shutdown
呼叫 close closesocket 函式意味著完全斷開連線,即不能傳送資料也不能接收資料,這種 生硬 的方式有時候會顯得不太 優雅 圖1 close closesocket 斷開連線 上圖演示了兩台正在進行雙向通訊的主機。主機a傳送完資料後,單方面呼叫 close closesocket 斷開...
「優雅」斷開的套接字連線
之前用的方法不夠優雅是因為,我們是呼叫close或closesocket函式單方面斷開連線。1.解釋tcp中 流 的概念。udp中能否形成流?請說明原因。答 兩台主機通過套接字建立連線後進入可交換資料的狀態,又稱 流形成的狀態 也就是把建立套接字後可交換資料的狀態看作是一種流,此處的流可以比作水流,...
網路程式設計學習筆記(七)優雅的斷開套接字連線
tcp中的斷開連線過程更重要,因為連線過程中一般不會出現大的變數,但斷開過程有可能發生意想不到的情況,因此應準確掌控。只有明白了下面講的半關閉 half close 才能明確斷開過程。linux的close函式和windows的closesocket函式意味著完全斷開連線。完全斷開不僅指無法傳輸資料...