日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

网络编程之shutdown() 与 close()函数详解

發布時間:2024/4/11 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 网络编程之shutdown() 与 close()函数详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1.close()函數 [cpp]?view plaincopyprint?
  • <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 plaincopyprint?
  • <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 plaincopyprint?
  • /*?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 plaincopyprint?
  • 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);??
  • ?} ?
  • 總結

    以上是生活随笔為你收集整理的网络编程之shutdown() 与 close()函数详解的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。