標籤:使用 os strong 資料 問題 代碼 時間 .net
1、 為了增加效率,可以考慮採用無異常的函數 在.net2.0中Socket.Send,Socket.Receive 有了無異常的函數 Socket.Send(Byte[], Int32, Int32, SocketFlags, SocketError) Socket.Receive(Byte[], Int32, Int32, SocketFlags, SocketError) 減少不必要的異常,就等於增加效率。
2、Socket.Connected 不是當前的Socket狀態 MSDN原文:擷取一個值,該值指示 Socket 是在上次 Send 還是 Receive 操作時串連到遠程主機。 應當如何解決呢?
同樣MSDN也告訴了我們: Connected 屬性的值反映最近操作時的串連狀態。如果您需要確定串連的目前狀態,請進行非阻止、零位元組的 Send 調用。 如果該調用成功返回或引發 WAEWOULDBLOCK 錯誤碼 (10035),則該通訊端仍然處於串連狀態;否則,該通訊端不再處於串連狀態。
3、要用Socket.Poll判斷是否可以接收,不要用Socket.Available 雖然Socket.Available可以偷窺到當前Recv緩衝區位元組數,而且Available是Poll速度的兩倍,但是MSDN說到:如果遠程主機使用 Shutdown 方法關閉了 Socket 串連,並且所有可用資料均已收到,則 Receive 方法將立即完成並返回零位元組。 所以當網路斷開的時候單純使用Socket.Available判斷是否recv到資料會存在不知道用戶端已經斷開Bug 補充:不推薦使用Socket.Poll對Socket的列表遍曆,應當使用Socket.Select(或者其他模型),Socket.Poll是對Socket.Select的封裝,執行Socket.Poll耗時是非阻塞Socket.Recv的三倍。
4、非阻塞模式不能採用Receive的傳回值表示是否斷開 第3條說道:如果遠程主機使用 Shutdown 方法關閉了 Socket 串連,並且所有可用資料均已收到,則 Receive 方法將立即完成並返回零位元組。但這並不能阻塞模式說明Socket已經斷開,這一條和C的recv函數不同,需要特別注意。需要判斷out出來的SocketError,當不為SocketError.Success、SocketError.Interrupted和SocketError.WouldBlock時就可以認為網路已經斷開。
5、Send可能出現緩衝區滿的情況 判斷out出來的SocketError,如果等於SocketError.WouldBlock,則是Send緩衝區已滿,應斷開該Socket,否則影響整體速度,而不應當again, 反過來說允許的錯誤碼只有SocketError.Interrupted,此時可以重來一次。
6、主動斷開Socket MSDN說道:如果當前使用的是連線導向的 Socket,則必須先調用 Shutdown 方法,然後才能關閉 Socket。這可以確保在已串連的通訊端關閉之前,已發送和接收該通訊端上的所有資料。 所以,網路程式庫的Close函數可以封裝為先調用 Shutdown(SocketShutdown.Both),在調用Close()。
7、Socket已經關閉(Close)但不能在另一端斷開 一端Scoket已經關閉了,但另一端短時間內仍可以發送資料!這個問題還沒有找到解決辦法的,但原因已知,在《Windows網路編程技術》一書(P139-P140)中說道:被動關閉的情況下,應用程式會從對方那裡接收一個FIN包,並用一個ACK包做出響應。此時,應用程式的通訊端會變成ClOSE_WAIT狀態。由於對方已關閉自己的通訊端,所以不能再發送資料了。但應用程式卻不同,它能一直發送資料,直到對方的通訊端已關閉為止。