2009-11-08 26 views
4

我有一個程序在c#中,我創建一個套接字,綁定它,開始聽,然後使用beginaccept! 但是當我嘗試關閉\關閉套接字時,我從beginaccept AsyncCallback方法中收到異常!BeginAccept方法後無法關閉套接字

 private void start_listening() 
     { 

      main_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
      IPEndPoint iplocal = new IPEndPoint(IPAddress.Any, 11150); 
      main_socket.Bind(iplocal); 
      main_socket.Listen(5); 
      main_socket.BeginAccept(new AsyncCallback(OnClientConnect), null); 
      } 


     private void Disconnect_Click(object sender, EventArgs e) 
     { 
      main_socket.Shutdown(SocketShutdown.Both); 
      main_socket.Close(); 
     } 

     public void OnClientConnect(IAsyncResult asyn) 
     { 

      try 
      { 
       clients[connected_clients] = new Client("CHANGEME", "127.0.0.1", this); 
       clients[connected_clients].Socket = main_socket.EndAccept(asyn); 
       clients[connected_clients].WaitForData(); 
       main_socket.BeginAccept(OnClientConnect, null); 
      } 
      catch (SocketException se) 
      { 
       MessageBox.Show(se.Message); 
      } 
} 

非常感謝!

回答

6

當main_socket關閉時,OnClientConnect()將被調用,但main_socket.EndAccept()應該拋出一個ObjectDisposedException。也許你想捕獲該異常並將其視爲「偵聽器套接字已關閉」消息。

你的代碼的另一個問題是main_socket實際上並沒有連接到任何東西。在Disconnect_Click()中調用main_socket.Shutdown()可能會拋出,但是這次它應該是一個SocketException,表示套接字未連接。我會刪除main_socket.Shutdown()調用。

+2

+1。不幸的是,沒有諸如「IsClosed」之類的屬性。套接字來自克蘇魯黑暗的非託管世界。 – Roubachof 2009-11-09 10:31:39

+1

實際上,有一種方法:如果套接字在連接的本地側關閉,則Socket.Handle將爲-1。 – Gonzalo 2009-11-09 18:26:00

+0

感謝球員的答案!我會檢查的。 所以你說,當我得到拋出onclientconnect因爲套接字是封閉的,我應該處理該excaption? – Hipno 2009-11-10 06:44:55

0

「要取消對BeginAccept方法的未決呼叫,請關閉套接字。在異步操作正在進行中調用Close方法時,將調用提供給BeginAccept方法的回調函數。 EndAccept方法將拋出ObjectDisposedException以指示該操作已被取消。「

Socket.BeginAccept Method (AsyncCallback, Object)

正確的方法可能是:
1)在服務器上創建客戶端套接字,連接到監聽套接字,併成功EndAccept後關閉它
2)通過MSDN建議的方式就是處理這個異常的是

1

舊主題,但一個解決方案是:保留一個本地變量,以跟蹤你什麼時候關閉/關閉套接字。我使用_isShutdown

當你開始監聽套接字時,設置_isShutDown = False;
之前關閉套接字,set _isShutdown = True;

EndAccept(iar)功能,只能調用

socket.EndAccept() when _isShutdown is false 
<pre><code> 
if (_isShutdown == false) 
{ 
someWorkSocket = listenSocket.EndAccept(iaSyncResult); 
//... 
} 
else 
{ 
//socket is closed, and we shouldn't use it. Should erase this else clause.. 
}