C# TcpClient BeginConnect超时
如何在c中为BeginConnect异步调用设置自定义超时? 这是非常有用的,当连接到主机时,有可能不在给定端口上侦听。每次这样的调用都会在释放线程之前浪费大约15秒的时间 正如许多答案所建议的,我有以下代码:C# TcpClient BeginConnect超时,c#,.net,sockets,timeout,C#,.net,Sockets,Timeout,如何在c中为BeginConnect异步调用设置自定义超时? 这是非常有用的,当连接到主机时,有可能不在给定端口上侦听。每次这样的调用都会在释放线程之前浪费大约15秒的时间 正如许多答案所建议的,我有以下代码: public bool Test() { using (var tcp = new TcpClient()) { var c = tcp.BeginConnect(IPAddress.Parse("8.8.8.8"), 8080, null, nul
public bool Test()
{
using (var tcp = new TcpClient())
{
var c = tcp.BeginConnect(IPAddress.Parse("8.8.8.8"), 8080, null, null);
var success = c.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(1));
if (!success)
{
Console.WriteLine("Before cleanup");
tcp.Close();
tcp.EndConnect(c);
Console.WriteLine("After cleanup");
throw new Exception("Failed to connect.");
}
}
return true;
}
然而,这不起作用。实际上,在调用之后,函数进入if开关,但它会立即在tcp上阻塞。关闭调用并等待15秒。它能以某种方式避免吗?我编写了一个简单的测试程序,使用两种不同的技术来实现您的目标,并测试您发布的确切代码。我无法再现您描述的问题。无论我是直接使用TcpClient还是Socket,在对象上调用Close都会在异步完成、异常处理、线程同步等之后,在不到十分之一秒的时间内立即完成连接操作 请注意,在TcpClient案例中,TcpClient类似乎有一个bug,它抛出的是NullReferenceException,而不是预期的ObjectDisposedException。这似乎是因为TcpClient在调用Close时将Client属性设置为null,但在调用完成委托时尝试使用该值。哎呀 这意味着在代码中,调用方将看到NullReferenceException,而不是您似乎想要抛出的异常。但这似乎不会造成实际的延迟 这是我的测试程序:
class Program
{
static void Main(string[] args)
{
_TestWithSocket();
_TestWithTcpClient();
try
{
_TestSOCode();
}
catch (Exception e)
{
Console.WriteLine("Exception: " + e);
}
}
private static void _TestSOCode()
{
using (var tcp = new TcpClient())
{
var c = tcp.BeginConnect(IPAddress.Parse("8.8.8.8"), 8080, null, null);
var success = c.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(1));
if (!success)
{
Console.WriteLine("Before cleanup");
tcp.Close();
tcp.EndConnect(c);
Console.WriteLine("After cleanup");
throw new Exception("Failed to connect.");
}
}
}
private static void _TestWithTcpClient()
{
TcpClient client = new TcpClient();
object o = new object();
Console.WriteLine("connecting TcpClient...");
client.BeginConnect("8.8.8.8", 8080, asyncResult =>
{
Console.WriteLine("connect completed");
try
{
client.EndConnect(asyncResult);
Console.WriteLine("client connected");
}
catch (NullReferenceException)
{
Console.WriteLine("client closed before connected: NullReferenceException");
}
catch (ObjectDisposedException)
{
Console.WriteLine("client closed before connected: ObjectDisposedException");
}
lock (o) Monitor.Pulse(o);
}, null);
Thread.Sleep(1000);
Stopwatch sw = Stopwatch.StartNew();
client.Close();
lock (o) Monitor.Wait(o);
Console.WriteLine("close took {0:0.00} seconds", sw.Elapsed.TotalSeconds);
Console.WriteLine();
}
private static void _TestWithSocket()
{
Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
object o = new object();
Console.WriteLine("connecting Socket...");
socket.BeginConnect("8.8.8.8", 8080, asyncResult =>
{
Console.WriteLine("connect completed");
try
{
socket.EndConnect(asyncResult);
Console.WriteLine("socket connected");
}
catch (ObjectDisposedException)
{
Console.WriteLine("socket closed before connected");
}
lock (o) Monitor.Pulse(o);
}, null);
Thread.Sleep(1000);
Stopwatch sw = Stopwatch.StartNew();
socket.Close();
lock (o) Monitor.Wait(o);
Console.WriteLine("close took {0:0.00} seconds", sw.Elapsed.TotalSeconds);
Console.WriteLine();
}
}
不幸的是,您没有提供一个实际完整的代码示例来演示这个问题。如果在您的环境中,上面的代码演示了您描述的问题,那么,由于在我的环境中没有演示,这显然意味着是您的环境导致了问题。不同的操作系统版本、不同的.NET版本等
在这种情况下,您应该明确环境中可能相关的特定方面
如果上面的代码示例按预期工作,并且没有演示您描述的问题,那么您只需要找出代码中的哪些不同之处并导致问题。在这种情况下,如果您仍然无法真正解决问题,您应该发布演示问题的帖子。可能重复的还有,手动处理和使用说明是什么?感谢您的评论,但是无论是否使用都没有关系。您的链接解决方案无效,并且存在于我的代码中。这和这里的问题相似:你们找到解决方案了吗?是卡巴斯基。它与常见端口(如8080和DNS 53)上的网络流量发生了冲突。尝试卸载并测试。仍然无法正常运行。我在项目属性中使用VS 2013,NET 4.5.1。赢得8.1完全补丁。我刚刚运行了您提到的作为控制台项目发布版的代码,得到了Socket->20s、TcpClient->20s、myCode->20s。SS:我还要求我的朋友运行你的代码,结果是一样的。对不起……听起来你和你的朋友,现在正在寻找你计算机上的一些特定配置问题。我自己在各种配置上测试了代码,包括一个与您的配置相匹配的配置以及一些Windows7机器上的配置,并且它们都正常工作。代码本身很好,这只会给您的特定计算机在.NET中的配置留下一些问题,或者可能是特定网络驱动程序和/或硬件配置的问题。您能用上面的代码为我编译发行版二进制文件吗?我还将尝试编译自己的,并在全新的Windows7虚拟机上进行测试。如果你的二进制代码有效。。那当然是VS/.NET问题了。@Josh:我不确定您希望我如何向您交付编译后的二进制文件。另外,至少考虑到我对Windows网络实现的深层次了解有限,因为我们不知道是什么环境差异导致了问题,因此认为即使在新的Windows 7虚拟机上,您也不会遇到同样的问题还为时过早。也就是说,您的本地网络环境可能会触发Windows或.NET中导致此延迟的某些行为。如果你想让我放一个二进制文件,我可以,但不要抱太大希望。我已经设法在新的Win7和Win8安装上测试了二进制文件。工作正常,在0.02秒内关闭连接。这意味着一些软件在我的电脑上把事情搞糟了。我和我的朋友有一个共同点就是卡巴斯基防病毒软件。稍后我将深入探讨这个问题,并发布我的研究结果。