2013-01-31 69 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