終止網路連線的常用方法是呼叫close函式。不過close有兩個限制,可以通過使用shutdown函式來避免。
(1)close把描述符的引用計數減1,僅在該計數變為0時才關閉套接字。而使用shutdown可以不管引用計數,就可以激發tcp的正常連線終止序列。
(2)close終止讀和寫兩個方向的資料傳輸。既然tcp連線是全雙工的,有時候我們需要告知對方,我們已經完成了資料傳送,即使對端仍有資料要傳送給我們。
呼叫shutdown可以關閉一半tcp連線,函式原型如下:
#include
intshutdown
(int sockfd,
int howto)
;
返回:若成功則為0,若出錯則為-1。
該函式的行為依賴於howto引數的值。
shut_rd關閉連線的讀一半——套接字中不再有資料可以接收,而且套接字接收快取區中的現有資料都被丟棄,程序不能再對該套接字呼叫任何讀函式。對於乙個tcp套接字在如此呼叫shutdown函式後,由該套接字接收的來自對端的任何資料都被確認,然後悄然丟棄。
shut_wr關閉連線的寫一半——這稱為半關閉。當前留在套接字傳送快取區中的資料將被傳送掉,後跟tcp的正常連線終止序列。在此,不管套接字描述符的引用計數是否等於0,寫半部關閉照樣執行。程序不能再對該套接字呼叫任何寫函式。
shut_rdwr連線的讀半部和寫半部都關閉—— 等效於兩次呼叫shutdown:第一次呼叫指定shut_rd,第二次呼叫指定shut_wr。
**注:**這三個shut_***名字由posix規範定義。howto引數的典型值將會是0(關閉讀半部)、1(關閉寫半部)和2(讀半部和寫半部都關閉)。
通常,unix close函式也用來關閉套接字,並終止tcp連線。
#include
intclose
(int sockfd)
;
返回:若成功則為0,若出錯則為-1
close乙個tcp套接字的預設行為是把該套接字標記成已關閉,然後立即返回到呼叫程序。該套接字描述符不能再由呼叫程序使用,也就是說它不能作為乙個read或write的第乙個引數。然而tcp將嘗試傳送已排隊等待傳送到對端的任何資料,傳送完畢後發生的是正常tcp連線終止序列。
特別的是:so_linger套接字選項可以用來改變tcp套接字的這種預設行為。
描述符引用計數
在併發伺服器中,父程序關閉已連線套接字,只是導致相應描述符的引用計數減1。既然引用計數值大於0,這個close呼叫並不引起tcp的四組連線終止序列。對於父程序與子程序共享已連線套接字的併發伺服器來說,正是所期望的。
如果我們確實想在某個tcp連線上傳送乙個fin,可以改用shutdown代替close。
如果父程序對每個由accept返回的已連線套接字都不呼叫close,那麼併發伺服器中將會發生什麼?
首先,父程序最終將耗盡可用描述符,因為任何程序在任何時刻可擁有著的開啟的描述符通常是有限制的。不過重要的是,沒有乙個客戶連線會被終止。當子程序關閉已連線套接字時,它的引用計數值將由2減為1,且保持為1,因為父程序永遠不關閉任何已連線套接字。這將妨礙tcp連線終止序列的發生,導致連線一直開啟著。
socket關閉的close和shutdown區別
socket關閉close和shutdown socket關閉有2個close,shutdown 他們之間的區別 close 關閉本程序的socket id,但鏈結還是開著的,用這個socket id的其它程序還能用這個鏈結,能讀或寫這個socket id shutdown 則破壞了socket 鏈...
socket程式設計 優雅的斷開連線shutdown
呼叫 close closesocket 函式意味著完全斷開連線,即不能傳送資料也不能接收資料,這種 生硬 的方式有時候會顯得不太 優雅 上圖演示了兩台正在進行雙向通訊的主機。主機a傳送完資料後,單方面呼叫 close closesocket 斷開連線,之後主機a b都不能再接受對方傳輸的資料。實際...
和 區別和聯絡, 和 區別和聯絡
和 區別和聯絡,和 區別和聯絡,實際專案中,什麼情況用哪種?首先,和 的聯絡 共同點 和 都可以用作 邏輯與 運算子,都是雙目運算子。具體要看使用時的具體條件來決定。無論使用哪種運算子,對最終的運算結果都沒有影響。情況1 當上述的運算元是boolean型別變數時,和 都可以用作邏輯與運算子。情況2 ...