Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.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# .NET套接字超时-关闭时阻塞方法_C#_.net_Sockets - Fatal编程技术网

C# .NET套接字超时-关闭时阻塞方法

C# .NET套接字超时-关闭时阻塞方法,c#,.net,sockets,C#,.net,Sockets,使用异步套接字调用实现连接超时时遇到问题 我的想法是在套接字对象上调用BeginConnect,然后在超时时间过后使用计时器调用套接字 只要在GUI线程上创建套接字,这就可以正常工作——Close方法立即返回,回调方法被执行。但是,如果套接字是在任何其他线程上创建的,则Close方法将阻塞,直到出现默认的IP超时 要复制的代码: private Socket client; private void button1_Click(object sender, EventArgs e) {

使用异步套接字调用实现连接超时时遇到问题

我的想法是在套接字对象上调用BeginConnect,然后在超时时间过后使用计时器调用套接字

只要在GUI线程上创建套接字,这就可以正常工作——Close方法立即返回,回调方法被执行。但是,如果套接字是在任何其他线程上创建的,则Close方法将阻塞,直到出现默认的IP超时

要复制的代码:

private Socket client;

private void button1_Click(object sender, EventArgs e) {
    // Creating the socket on a threadpool thread causes Close to block.
    ThreadPool.QueueUserWorkItem((object state) => {
        client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        IAsyncResult result = client.BeginConnect(IPAddress.Parse("144.1.1.1"), 23, new AsyncCallback(CallbackMethod), client);

        // Wait for 2 seconds before closing the socket.
        if (result.AsyncWaitHandle.WaitOne(2000)) {
            MessageBox.Show("Connected.");
        } else {
            MessageBox.Show("Timed out. Closing socket...");
            client.Close();
            MessageBox.Show("Socket closed.");
        }
    });
}

private void CallbackMethod(IAsyncResult result) {
    MessageBox.Show("Callback started.");
    Socket client = result.AsyncState as Socket;
    try {
        client.EndConnect(result);
    } catch (ObjectDisposedException) {
    }
    MessageBox.Show("Callback finished.");
}
如果删除QueueUserWorkItem行,并在GUI线程上创建套接字,则套接字会立即关闭而不会阻塞

有人能解释一下发生了什么事吗?
谢谢

编辑-系统.Net跟踪输出似乎有所不同,这取决于它是在GUI线程上连接还是在其他线程上连接:


您是否尝试过删除围绕Socket.Close()调用的“MessageBox.Show”调用?

我无法理解的是,为什么它会在GUI线程上立即关闭。在调用client.Close()之前,我会尝试调用client.Shutdown()


我还尝试在常规线程(thread.Start())中运行套接字对象,而不是使用线程池。这样,您就可以保留对线程的引用,并自己调用thread.Interrupt()和/或thread.Abort()。

关闭时的阻塞发生与MessageBox.Show无关。即使在超时为零的情况下将套接字的属性设置为true也无济于事。来自MSDN:“下表描述了Enabled属性和LingerState属性中存储的LingerTime属性的可能值的Close方法的行为。”当LingerState已启用且LingerTime设置为零时:“丢弃所有挂起的数据。对于面向连接的套接字(例如TCP),Winsock重置连接。”我尝试用上述程序重新编程。我无法重新编程。程序没有挂起。这在Windows 7和XP模式下的任何版本的.NET Framework上都会发生。我也可以在不同的机器上复制它。程序不应该挂起,但是在“超时。关闭套接字…”消息和“套接字关闭。”消息之间应该有大约20秒的延迟。尝试获取tracelog(请参阅),并将日志文件放在pastebin.com上。我可以看一下。谢谢你,我已经编辑了我的问题,包括跟踪日志。底层套接字调用似乎因调用它们的线程而异。在套接字连接之前调用Shutdown会导致SocketException-“发送或接收数据的请求被禁止,因为套接字未连接,并且(使用sendto调用在数据报套接字上发送时)未提供地址”。我目前正在使用一个线程启动多个BeginConnect,然后使用System.Timers.Timer根据需要超时套接字-我不能为每个连接使用新线程:(