【问题标题】:C# TcpClient TimeoutC# TcpClient 超时
【发布时间】:2015-10-04 23:01:32
【问题描述】:

我正在尝试连接到本地网络内的路由器。到目前为止,我已经使用了 TcpClient。

检查我的代码:

public static void RouterConnect()
        {    
            TcpClient tcpClient = new TcpClient("192.168.180.1",23); <-- Timeout comes up here
            tcpClient.ReceiveTimeout = 2000; // Not working
            tcpClient.SendTimeout = 2000; // Also not working
            NetworkStream nStream = tcpClient.GetStream(); <-- thought Timeout would raise here

            // Further code here. But already tested while commented out. 
            // So everything else expect the code above shouldnt be relevant.
        }

我想添加一个设置表单(router-ip/user/password)。因此,在用户输入不存在的主机 IP 的情况下,用户端可能会失败。

当前的超时时间约为 20 秒,这太高了。 TcpClient.ReceiveTimeoutTcpClient.SendTimeout 没有设置正确的超时时间,因为我已经尝试过了。 Google 没有帮我解决这个问题。

那么,有人知道如何为此设置正确的超时时间吗?我读过异步。我不想使用的连接。一个更干净的 1-line-timeout-set 会很好。可能吗?

非常感谢!

编辑 1: 在调试时仔细观察,我注意到超时已经在 tcpClient 的初始化(如上面在我的代码中编辑的那样)提高,而不是我之前在.GetStream() 认为的那样。


编辑解决方案:

由于没有人发布我选择的解决方案中的工作代码,因此它是如何工作的:

public static void RouterConnect()
        {
            TcpClient tcpClient = new TcpClient();
            if(tcpClient.ConnectAsync("192.168.80.1",23).Wait(TimeSpan.FromSeconds(2)))
            {
                NetworkStream nStream = tcpClient.GetStream();
            }
            else
            {
                MessageBox.Show("Could not connect!");
            }
        }

【问题讨论】:

  • 你在哪里从流中读取?
  • 它稍后出现,但我猜不相关。我评论了阅读。超时出现在我上面在 tcpClient 初始化时编辑的代码中。
  • TcpClient 的构造函数还有connects the client 到端点。
  • @cubrr 是的,谢谢。大约5分钟前才注意到。无论如何,我的问题保持不变。
  • 我想你的问题类似于this one。如果您的目标是 .NET 4.5,this answer 可能会成功。

标签: c# timeout tcpclient networkstream socketexception


【解决方案1】:

我知道的唯一方法是使用异步方法。 .Net 4.5 中有一个不错的新异步方法,它返回一个任务,您可以像这样等待:

tcpClient.ConnectAsync().Wait(timeout)

如果不成功则返回 false。

【讨论】:

  • 我会检查一下。它与我在问题下的 cmets 中注意到的 cubrr 完全相同。
【解决方案2】:

是的,我想最干净的方法是使用TcpClient.BeginConnect 方法。

因此,无论您是否可以连接到端点,您都会收到异步反馈。 另请参阅: Async Connect

【讨论】:

  • 关于您的编辑:是的,指导老师也调用了连接。作为替代方案,您可以调用空构造函数,然后使用 Connect 或 BeginConnect
【解决方案3】:

您使用的当前构造函数重载方法也在连接,因此在连接之前会阻塞您。

此外TcpClient 上没有属性可以控制TcpClient 超时。

来自MSDNTcpClient(String, Int32)

初始化 TcpClient 类的新实例并连接到 指定主机上的指定端口。

Social MSDN的替代代码

using (vartcp = new TcpClient())  
{  
    IAsyncResult ar = tcp.BeginConnect("192.168.180.1", 23, null, null);  
    System.Threading.WaitHandle wh = ar.AsyncWaitHandle;  
    try 
    {  
       if (!ar.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(2), false))  
       {  
           tcp.Close();  
           throw new TimeoutException();  
       }  

        tcp.EndConnect(ar);  
    }  
    finally 
    {  
        wh.Close();  
    }  
} 

【讨论】:

  • 第一步看起来不错。不幸的是,它停留在 20 秒。
  • 那些超时属性不会影响Connect 方法。
猜你喜欢
  • 1970-01-01
  • 2015-03-25
  • 2012-12-01
  • 2013-02-22
  • 2019-03-11
  • 1970-01-01
  • 2012-12-04
  • 1970-01-01
  • 2013-06-11
相关资源
最近更新 更多