Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# TcpClient BeginConnect超时_C#_.net_Sockets_Timeout - Fatal编程技术网

C# TcpClient BeginConnect超时

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

如何在c中为BeginConnect异步调用设置自定义超时? 这是非常有用的,当连接到主机时,有可能不在给定端口上侦听。每次这样的调用都会在释放线程之前浪费大约15秒的时间

正如许多答案所建议的,我有以下代码:

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秒内关闭连接。这意味着一些软件在我的电脑上把事情搞糟了。我和我的朋友有一个共同点就是卡巴斯基防病毒软件。稍后我将深入探讨这个问题,并发布我的研究结果。