国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

linux編程中close與shutdown的區別

2019-11-08 20:03:58
字體:
來源:轉載
供稿:網友

轉自 http://blog.csdn.net/lgp88/article/details/7176509

1.close()函數

[cpp] view plain copy PRint?<span style="font-size:13px;">#include<unistd.h>  int close(int sockfd);     //返回成功為0,出錯為-1.</span>  

    close 一個套接字的默認行為是把套接字標記為已關閉,然后立即返回到調用進程,該套接字描述符不能再由調用進程使用,也就是說它不能再作為read或write的第一個參數,然而TCP將嘗試發送已排隊等待發送到對端的任何數據,發送完畢后發生的是正常的TCP連接終止序列。

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

2.shutdown()函數

[cpp] view plain copy print?<span style="font-size:13px;">#include<sys/socket.h>  int shutdown(int sockfd,int howto);  //返回成功為0,出錯為-1.</span>  

    該函數的行為依賴于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() ){   /*      The child, it copies its stdin to the socket              */         while( gets(buffer) >0)             write(s,buf,strlen(buffer));             close(s);             exit(0);     }     else {          /* The parent, it receives answers  */          while( (n=read(s,buffer,sizeof(buffer)){              do_something(n,buffer);              /* Connection break from the server is assumed  */              /* ATTENTION: deadlock here                     */           wait(0); /* Wait for the child to exit          */           exit(0);      }  

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

[cpp] view plain copy print?if( fork() ) {  /* The child                    */        while( gets(buffer)           write(s,buffer,strlen(buffer));        shutdown(s,1); /* Break the connection                         *for writing, The server will detect EOF now. Note: reading from                   *the socket is still allowed. The server may send some more data                   *after receiving EOF, why not? */        exit(0);   }  
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 全椒县| 广南县| 武隆县| 福海县| 琼中| 南江县| 临城县| 宝兴县| 四子王旗| 隆昌县| 五家渠市| 正蓝旗| 嘉鱼县| 右玉县| 手机| 油尖旺区| 娄烦县| 淳安县| 辰溪县| 台东市| 江永县| 革吉县| 大埔区| 泰兴市| 莱州市| 新龙县| 商南县| 黎城县| 南皮县| 金坛市| 高邮市| 历史| 宁晋县| 洛南县| 织金县| 梁山县| 合水县| 卢湾区| 如皋市| 门头沟区| 锡林浩特市|