linux程式設計中close與shutdown的區別

2021-07-27 00:00:25 字數 2100 閱讀 8468

**

1.close()函式

[cpp]view plain

copy

print?

"font-size:13px;"

>#include

intclose(

intsockfd);     

//返回成功為0,出錯為-1.

close 乙個套接字的預設行為是把套接字標記為已關閉,然後立即返回到呼叫程序,該套接字描述符不能再由呼叫程序使用,也就是說它不能再作為read或write的第乙個引數,然而tcp將嘗試傳送已排隊等待傳送到對端的任何資料,傳送完畢後發生的是正常的tcp連線終止序列。

在多程序併發伺服器中,父子程序共享著套接字,套接字描述符引用計數記錄著共享著的程序個數,當父程序或某一子程序close掉套接字時,描述符引用計數會相應的減一,當引用計數仍大於零時,這個close呼叫就不會引發tcp的四路握手斷連過程。

2.shutdown()函式

[cpp]view plain

copy

print?

"font-size:13px;"

>#include

intshutdown(

intsockfd,

inthowto);  

//返回成功為0,出錯為-1.

該函式的行為依賴於howto的值

1.shut_rd:值為0,關閉連線的讀這一半。

2.shut_wr:值為1,關閉連線的寫這一半。

3.shut_rdwr:值為2,連線的讀和寫都關閉。

終止網路連線的通用方法是呼叫close函式。但使用shutdown能更好的控制斷連過程(使用第二個引數)。

3.兩函式的區別

close與shutdown的區別主要表現在:

close函式會關閉套接字id,如果有其他的程序共享著這個套接字,那麼它仍然是開啟的,這個連線仍然可以用來讀和寫,並且有時候這是非常重要的 ,特別是對於多程序併發伺服器來說。

shutdown會切斷程序共享的套接字的所有連線,不管這個套接字的引用計數是否為零,那些試圖讀得程序將會接收到eof標識,那些試圖寫的程序將會檢測到sigpipe訊號,同時可利用shutdown的第二個引數選擇斷連的方式。

下面將展示乙個客戶端例子片段來說明使用close和shutdown所帶來的不同結果:

客戶端有兩個程序,父程序和子程序,子程序是在父程序和伺服器建連之後fork出來的,子程序傳送標準輸入終端鍵盤輸入資料到伺服器端,直到接收到eof標識,父程序則接受來自伺服器端的響應資料。

[cpp]view plain

copy

print?

/* first  sample client fragment,

* 多餘的**及變數的宣告已略       */

s=connect(...);  

if( fork() )  

else  

對於這段**,我們所期望的是子程序獲取完標準終端的資料,寫入套接字後close套接字,並退出,伺服器端接收完資料檢測到eof(表示資料已傳送完),也關閉連線,並退出。接著父程序讀取完伺服器端響應的資料,並退出。然而,事實會是這樣子的嘛,其實不然!子程序close套接字後,套接字對於父程序來說仍然是可讀和可寫的,儘管父程序永遠都不會寫入資料。因此,此socket的斷連過程沒有發生,因此,伺服器端就不會檢測到eof標識,會一直等待從客戶端來的資料。而此時父程序也不會檢測到伺服器端發來的eof標識。這樣伺服器端和客戶端陷入了死鎖(deadlock)。如果用shutdown代替close,則會避免死鎖的發生。

[cpp]view plain

copy

print?

if( fork() )   

Linux檔案程式設計之 系統呼叫 close

1 相關函式說明 相關函式 open,fcntl,shutdown,unlink,fclose 表頭檔案 include 定義函式 int close intfd 引數說明 引數fd為先前由open 或creat 所返回的檔案描述詞。當使用完檔案後若已不再需要則可使用close 關閉該檔案,而clo...

linux系統中device tree的SPI描述

spi匯流排可以使用乙個spi主裝置節點和多個spi從裝置為子節點描述。想要在dev目錄中產生乙個spidev節點的話可以增加下面的描述 spidev1 spidev 0 end spidev 0 spidev1 最新的核心遇到compatible spidev 這個屬性會報出warnning,建議...

Python中 r與 s的區別

r是rper 方法處理的物件 s是str 方法處理的物件 其實有些情況下,兩者處理的結果是一樣的,比如說處理資料型別為int型物件 例如1 print i am d year old.22 print i am s year old.22 print i am r year old.22 返回的結果...