C# 如果socket.connect()函数发生故障,如何停止它?

C# 如果socket.connect()函数发生故障,如何停止它?,c#,multithreading,.net-micro-framework,netduino,C#,Multithreading,.net Micro Framework,Netduino,我面临停止socket.connect()函数的问题。 有时,我的本地计算机和远程计算机之间的物理链接可能很好,但由于某些原因,无法访问远程端点,可能是防火墙或远程计算机上的端口已关闭。在这种情况下,socket.connection()函数将被卡在那里并等待无限长的时间…即使防火墙稍后被禁用,该函数仍将永远卡在那里 因此,当遇到上述情况时,我试图找到停止socket.connect()的方法 问题是我使用的是一个.net微框架,其中没有超时机制、任务或套接字 我正在尝试使socket.conn

我面临停止socket.connect()函数的问题。 有时,我的本地计算机和远程计算机之间的物理链接可能很好,但由于某些原因,无法访问远程端点,可能是防火墙或远程计算机上的端口已关闭。在这种情况下,socket.connection()函数将被卡在那里并等待无限长的时间…即使防火墙稍后被禁用,该函数仍将永远卡在那里

因此,当遇到上述情况时,我试图找到停止socket.connect()的方法

问题是我使用的是一个.net微框架,其中没有超时机制、任务或套接字

我正在尝试使socket.connect()本身成为一个线程,如果(!thread.join(2000))。但是,我不太理解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  
    }

如果您的框架支持非阻塞连接,您可以尝试以下代码。这是我在Win7中为.NET4编写的

        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");
Socket Socket=新套接字(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
Console.WriteLine(“尝试连接”);
socket.Blocking=false;
尝试
{
插座连接(“8.8.8.8”,5050);
}
捕获(例外情况除外)
{
如果(ex为SocketException)&((SocketException)ex).ErrorCode==10035)//存在套接字问题,而该问题是由于处于非阻塞模式?那么这只是一个警告
{
//正在等待连接
整数时间=0;
而(时间<1000)//如果小于1秒
{
//做你想做的
if(socket.Connected)//如果已连接,则断开
打破
System.Threading.Thread.Sleep(50);//等待50miliec
时间+=50;
}
}
其他的
{
控制台写入线(“失败”);
}
}
如果(!socket.Connected)
控制台写入线(“中止”);
其他的
控制台。写入线(“连接”);

建议通过忙等待使
连接
呼叫超时。我强烈反对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无法关机,您会烧掉电池

是的,中止是不明智的。在你理解它之前不要使用它(你现在不理解它,但正在使用它)。@usr ya,我知道,但似乎我没有其他选择。除了使用线程进行连接,你可以创建一个超时线程。然后,您可以离开第二个线程,而不需要任何代码,如中止或中断。它会自动清洗。而且。线程.Abort在.net 1.1和.net 2天内不安全。它不太安全,而且仍然不起作用,因为Abort不能中止IO。这帮不了你。检测到超时后处理套接字。如何将超时设置为特定值?忙着等待有什么办法吗?忙着等待是一种有效的技巧+1.当然,你必须明白,默认情况下,它不会睡眠10毫秒,而是40-50秒。。是吗?;)很遗憾,我的平台不支持非阻塞连接。不过还是要谢谢你。@usr忙着等待是当你有一个套接字时,你能用非阻塞套接字做一些事情的唯一方法。关于超时,您需要将这一行:while(时间<1000)更改为您想要的任何毫秒数。这是正确的答案,因为这是在.net micro framework中执行此操作的唯一方法。这是因为它不支持套接字上的异步操作。作为任务替换,使用
新线程(()=>{Thread.Sleep(1000);theSocket.Close();}).Start()
@Nico即使使用异步操作,代码看起来也一样。简单地放弃异步IO并不是一个好主意,因为它会继续消耗资源、网络流量和端口。我并没有说这是一个好主意,但这是在.net micro framework中实现这一点的唯一方法,OP的问题正是基于此。