2013-01-31 68 views
2

我正在面臨停止socket.connect()函數的問題。 有時我的本地機器和遠程機器之間的物理連接可能很好,但由於某種原因,遠程終端無法訪問,可能是防火牆或遠程機器上的端口關閉。在這種情況下,socket.connection()函數將停留在那裏並等待無限的長時間......即使防火牆稍後被禁用,該函數仍然會永久停留在那裏。如何阻止socket.connect()函數?

所以我試圖找到一種方法來阻止socket.connect()當面臨上述情況。

事情是我使用.net微型框架,其中我沒有超時機制或任務或socket.beginconnect(); (!thread.join(2000))我試圖使socket.connect()本身是一個線程,並試圖在2秒後中止()它。但是,我不太明白abort()函數,我聽說它是​​一種不明智的方式來執行此操作,並且它不起作用。

現在我不知道該怎麼辦呢?誰能幫忙? thx很多

main function 
{ 
m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//Set up socket  
remoteEndPoint = new IPEndPoint(IPAddress.Parse(IP_add), 30000); 
m_socket.Connect(remoteEndPoint); 
myThread.Start(); 
     if (!myThread.Join(2000)) 
     { 
      Debug.Print(myThread.ThreadState.ToString()); 
      myThread.abort();      
     } 
} 

private static void socket_connect() 
    { 
     m_socket.Connect(remoteEndPoint);//Connect to remote device 
    } 
+0

是,放棄是不明智的。直到你理解它之前不要使用它(你現在不理解但正在使用它)。 – usr

+0

@usr雅,我知道,但似乎我沒有其他選項 – henryyao

+0

而不是使用線程進行連接,您可以創建一個線程超時。然後,您可以離開第二個線程,而不需要任何代碼,如中止或中斷。它會自動清理。 –

回答

0

如果你的框架支持非阻塞連接,你可以試試這個代碼。我在Win7中爲.net 4寫了這個。

 Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
     Console.WriteLine("Trying to connect"); 
     socket.Blocking = false; 
     try 
     { 
      socket.Connect("8.8.8.8", 5050); 
     } 
     catch (Exception ex) 
     { 
      if (ex is SocketException) && ((SocketException)ex).ErrorCode == 10035) // There is a socket problem and this problem is because of being in non-blocking mode? Then this is just a warning 
      { 
       // Waiting for connection 
       int time = 0; 
       while (time < 1000) // If it was lower than 1 second 
       { 
        // Do what you want 
        if (socket.Connected) // If connected then break 
         break; 
        System.Threading.Thread.Sleep(50); // Wait 50milisec 
        time += 50; 
       } 
      } 
      else 
      { 
       Console.WriteLine("Failed"); 
      } 
     } 

     if (!socket.Connected) 
      Console.WriteLine("Aborted"); 
     else 
      Console.WriteLine("Connected"); 
+0

如何將超時設置爲某個值?有沒有辦法解決忙碌的等待問題? – usr

+2

繁忙的等待是一種有效的技術。 +1 ...當然,你必須明白,默認情況下,它不會睡10毫秒,但評價者40-50 .. ja? ;) –

+0

不好意思,我的平臺不支持非阻塞連接。但無論如何感謝。 – henryyao

1

有人建議通過忙等待使Connect呼叫超時。我強烈反對a)該哲學和b)WinSock沒有提供更好的方法來解決這個常見問題的提議。

這裏是一個更好的解決方案:

 using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) 
     { 
      Task.Factory.StartNew(() => 
       { 
        Thread.Sleep(1000); 
        socket.Close(); 
       }); 
      try 
      { 
       socket.Connect("192.168.2.123", 1234); 
      } 
      catch (SocketException sex) 
      { 
       if (sex.ErrorCode == 10038) 
        Console.WriteLine("Timeout"); 
       else 
        throw; 
      } 
     } 

你自己檢測超時和關閉套接字。該程序需要大約1秒的時間才能運行,以便超時機制起作用。

請注意,上面的代碼是演示代碼,應該使用計時器並使其無比賽。

忙碌等待怎麼回事?

  • 壞維持
  • 在許多插座的情況下推出延遲
  • 法律約束的問題。在服務器系統
  • 在客戶端上的CPU不能斷電,完全非首發你燒你的電池
+1

這是正確的答案,因爲它是在.net微型框架中完成它的唯一方法。這是因爲它不支持套接字上的異步操作。作爲任務replacment使用 '新主題(()=> { Thread.sleep代碼(1000); theSocket.Close(); })。啓動();' – Nico

+0

@Nico即使異步操作的代碼看起來一樣。簡單地放棄異步IO並不是一個好主意,因爲它會繼續佔用資源,網絡流量和端口。 – usr

+0

我沒有說它是一個好主意,但它是在OP的問題所基於的.net微觀框架中完成的唯一方法。 – Nico