程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> (轉載) socket:10038錯誤{winSock的一個bug:當closesocket多次錯誤使用時會導致問題},10038closesocket

(轉載) socket:10038錯誤{winSock的一個bug:當closesocket多次錯誤使用時會導致問題},10038closesocket

編輯:C++入門知識

(轉載) socket:10038錯誤{winSock的一個bug:當closesocket多次錯誤使用時會導致問題},10038closesocket


這幾天想在一個開源的代碼上進行修改,以期研發出一個產品出來。
       程序原來是單線程網絡程序,需要修改為多線程,修改之後,總是出問題,輔助線程中的recv函數總是運行一陣子之後收到長度為-1的數據報,導致程序運行不正確甚至崩潰。
        由於是多線程,只好打日志進行調試,發現一個奇怪的問題。在A線程與B線程中,均使用了socket這個函數來產生socket,竟然會產生兩個相同返回值的socket!也就是說,A線程與B線程能同時獲得socket值為360的socket,這樣當A正在使用360進行數據接收時,B去連接一把,A自然就出錯了。

        這個問題實在是詭異,因為socket又不是COM組件,是可以直接在線程中共享的,究竟是出了什麼問題呢,MSDN和網絡上沒有見到任何與此問題相關的內容。活脫脫地就是API出錯了!按道理這是不可能的事情啊。
         實在沒轍了,只好review代碼,發現程序中有很多這樣的語句:
        if( mSocket != INVALID_SOCKET )
        {
                closesocket( mSocket );
         }
        這句有什麼問題沒有?呵呵看起來沒什麼問題,但是,不容置疑的是,肯定會導致一個socket被關閉多次。本著死馬當著活馬醫的原則,進行修改,每次closesocket之後,將socket的值置為INVALID_SOCKET,運行程序,問題解決。

         這個問題也太ft了,windows竟然連這個容錯都沒有做,按道理這是很好做的,socket實際上只是一個索引值,系統內核在關閉時如果發現已經關閉就不要做操作就可以了。現在看起來,內核裡面貌似是一個socket緩沖池,程序在使用的時候使用計數來管理生命周期。這樣當一個socket被關閉多次後,再創建改socket之後,系統可能會認為該socket是關閉的(因為計數小於等於0)。所以下次分配的時候,會將該索引重新分配出去。

       該問題在vista home版上出現,其他平台又沒有問題不得而知,由此可以看出成對編碼的好處以及面向對象封裝的好處。

 

轉自:http://blog.csdn.net/chen495810242/article/details/42029825

個人注釋:在win7上的測試結果,當一個工程調用多個dll的時候,不同的dll之間使用socket這個函數來產生socket,返回值是可能一樣的,就會發生連接無緣無故被斷開的現象,查了兩三天的說

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved