Yongq Wong

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

TcpClient.Connect函数连接超时的问题

问题原述:

http://topic.csdn.net/t/20060616/15/4825920.html

调用TcpClient.Connect函数连接其他机器。我在一台机器上测试程序,对于连接根本无法连接(物理连接不通)的机器,该函数用时5秒左右返回,并捕获SocketException异常。我在另一台机器上测试时,Connect函数用时26秒左右的时间才返回。请问有没有方法设置Connect函数连接超时的时间,如果超过一定时间还没有连上则返回。

解决方法:

   写了个帮助类,用了线程池  
   
  class   TcpClientConnector  
  {  
          ///   <summary>  
          ///   在指定时间内尝试连接指定主机上的指定端口。  
          ///   </summary>  
          ///   <param   name="hostname">要连接到的远程主机的   DNS   名。</param>  
          ///   <param   name="port">要连接到的远程主机的端口号。</param>  
          ///   <param   name="millisecondsTimeout">要等待的毫秒数,或   -1   表示无限期等待。</param>  
          ///   <returns>已连接的一个   TcpClient   实例。</returns>  
          ///   <remarks>本方法可能抛出的异常与   TcpClient   的构造函数重载之一  
          ///   public   TcpClient(string,   int)   相同,并若指定的等待时间是个负数且不等于  
          ///   -1,将会抛出   ArgumentOutOfRangeException。</remarks>  
          public   static   TcpClient   Connect(string   hostname,   int   port,   int   millisecondsTimeout)  
          {  
                  ConnectorState   cs   =   new   ConnectorState();  
                  cs.Hostname   =   hostname;  
                  cs.Port   =   port;  
                  ThreadPool.QueueUserWorkItem(new   WaitCallback(ConnectThreaded),   cs);  
                  if   (cs.Completed.WaitOne(millisecondsTimeout,   false))  
                  {  
                          if   (cs.TcpClient   !=   null)   return   cs.TcpClient;  
                          throw   cs.Exception;  
                  }  
                  else  
                  {  
                          cs.Abort();  
                          throw   new   SocketException(11001);   //   cannot   connect  
                  }  
          }  
   
          private   static   void   ConnectThreaded(object   state)  
          {  
                  ConnectorState   cs   =   (ConnectorState)state;  
                  cs.Thread   =   Thread.CurrentThread;  
                  try  
                  {  
                          TcpClient   tc   =   new   TcpClient(cs.Hostname,   cs.Port);  
                          if   (cs.Aborted)  
                          {  
                                  try   {   tc.GetStream().Close();   }  
                                  catch   {   }  
                                  try   {   tc.Close();   }  
                                  catch   {   }  
                          }  
                          else  
                          {  
                                  cs.TcpClient   =   tc;  
                                  cs.Completed.Set();  
                          }  
                  }  
                  catch   (Exception   e)  
                  {  
                          cs.Exception   =   e;  
                          cs.Completed.Set();  
                  }  
          }  
   
          private   class   ConnectorState  
          {  
                  public   string   Hostname;  
                  public   int   Port;  
                  public   volatile   Thread   Thread;  
                  public   readonly   ManualResetEvent   Completed   =   new   ManualResetEvent(false);  
                  public   volatile   TcpClient   TcpClient;  
                  public   volatile   Exception   Exception;  
                  public   volatile   bool   Aborted;  
                  public   void   Abort()  
                  {  
                          if   (Aborted   !=   true)  
                          {  
                                  Aborted   =   true;  
                                  try   {   Thread.Abort();   }  
                                  catch   {   }  
                          }  
                  }  
          }  
  }  
   
  =================================  
  用法示例:  
   
  try  
  {  
          Console.WriteLine("Connecting   to   nonexistenthost...");  
          TcpClient   tc   =   TcpClientConnector.Connect("nonexistent",   80,   1000);  
          Console.WriteLine("Returned");  
          try   {   tc.GetStream().Close();   }  
          catch   {   }  
          try   {   tc.Close();   }  
          catch   {   }  
  }  
  catch   (Exception   e)  
  {  
          Console.WriteLine("Exception:   "   +   e.Message);  
  }  

posted on 2009-04-29 11:37  Yongq wong  阅读(1602)  评论(1编辑  收藏  举报