C# TcpClient 超时问题

4

我正在尝试在本地网络内连接我的路由器。到目前为止,我已经使用了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.
        }

我想添加一个设置表单(路由器IP /用户/密码)。因此,可能存在用户端失败的情况,其中用户键入不存在的主机IP。
当前的超时时间约为20秒,这太长了。 TcpClient.ReceiveTimeoutTcpClient.SendTimeout不是要设置的正确超时时间,因为我已经尝试过了。谷歌没有帮助我解决这个问题。
那么,有人知道如何以正确的方式设置超时时间吗?我已经阅读了关于异步连接的内容,但我不想使用它们。一个更清晰的一行超时设置会很好。可能吗?
非常感谢!
编辑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!");
            }
        }

1
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - cbr
@cubrr 是的,谢谢。就在大约5分钟前我注意到了这一点。不管怎样,我的问题还是一样的。 - C4d
1
我猜你的问题类似于这个。如果你的目标是.NET 4.5,那么这个答案可能会解决问题。 - cbr
是的,异步连接。如上所述,我希望能够避免它。看起来我没有机会选择其他方式了。 - C4d
由于我的解决方案未被列在下面,我将编辑(附加)我的解决方案到我的问题中,并标记最接近的答案。感谢您们! - C4d
显示剩余7条评论
3个回答

1
我唯一知道的方法是使用异步方法。 在 .Net 4.5 中有一个很好的新异步方法,它返回一个 Task,你可以像这样等待它:
tcpClient.ConnectAsync().Wait(timeout)

如果不成功,它返回 false。

我会去看一下。就像Cubrr在我的问题下面评论里注意到的那样,它相当相似。 - C4d

0

嗯,我认为最干净的方法应该是使用TcpClient.BeginConnect方法。

这样你就可以异步地得到连接到端点的反馈,无论成功与否。 另外请参考: 异步连接


关于你的编辑:是的,构造函数也调用 connect。作为替代方案,您可以调用空构造函数,然后使用 Connect 或 BeginConnect。 - darkfirewave

0

你目前使用的构造函数重载方法也是连接的,因此会阻塞你,直到它连接成功。

此外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秒。 - C4d
1
这些超时属性不会影响Connect方法。 - cbr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接