作者:RazanPaul

译者:Todd Wei

原文:http://www.codeproject.com/KB/IP/TimeOutSocket.aspx

介绍

您可能注意到了,.Net的System.Net.Sockets.TcpClient和System.Net.Sockets.Socket都没有直接为Connect/BeginConnect提供超时控制机制。因此,当服务器未处于监听状态,或者发生网络故障时,客户端连接请求会被迫等待很长一段时间,直到抛出异常。默认的等待时间长达20~30s。.Net Socket库的SocketOptionName.SendTimeout提供了控制发送数据的超时时间,但并非本文讨论的连接请求的超时时间。

背景

这个问题最初源于我的某个项目,在解决以后,我曾将关键代码发表在自己的博客上。我注意到不少人对此表示感谢,所以我想这是一个常见的问题,或许很多人都需要解决它。

实现

下面是实现的关键代码:


class TimeOutSocket
{
    private static bool IsConnectionSuccessful = false;
    private static Exception socketexception;
    private static ManualResetEvent TimeoutObject = new ManualResetEvent(false);     public static TcpClient Connect(IPEndPoint remoteEndPoint, int timeoutMSec)
    {
        TimeoutObject.Reset();
        socketexception = null;           string serverip = Convert.ToString(remoteEndPoint.Address);
        int serverport = remoteEndPoint.Port;           
        TcpClient tcpclient = new TcpClient();
        
        tcpclient.BeginConnect(serverip, serverport, 
            new AsyncCallback(CallBackMethod), tcpclient);         if (TimeoutObject.WaitOne(timeoutMSec, false))
        {
            if (IsConnectionSuccessful)
            {
                return tcpclient;
            }
            else
            {
                throw socketexception;
            }
        }
        else
        {
            tcpclient.Close();
            throw new TimeoutException("TimeOut Exception");
        }
    }
    private static void CallBackMethod(IAsyncResult asyncresult)
    {
        try
        {
            IsConnectionSuccessful = false;
            TcpClient tcpclient = asyncresult.AsyncState as TcpClient;
             
            if (tcpclient.Client != null)
            {
                tcpclient.EndConnect(asyncresult);
                IsConnectionSuccessful = true;
            }
        }
        catch (Exception ex)
        {
            IsConnectionSuccessful = false;
            socketexception = ex;
        }
        finally
        {
            TimeoutObject.Set();
        }
    }
}

这里,ManualResetEvent的WaitOne(TimeSpan, Boolean)起到了主要的作用。它将阻止当前线程,直到ManualResetEvent对象被Set或者超过timeout时间。上面的代码中,调用BeginConnect后通过WaitOne方法阻止当前线程,如果在timeoutMSec时间内连接成功,将在CallBackMethod回调中调用TimeoutObject.Set,解除被阻塞的连接线程并返回;否则,连接线程会在等待超时后,主动关闭连接并抛出TimeoutException。

总结

虽然实现非常简单,但或许很多人都需要连接请求超时机制,如果有任何问题,我会尽力为您解答。

C# Socket连接请求超时机制的更多相关文章

  1. C# Socket.Connect连接请求超时机制

    介绍 您可能注意到了,.Net的System.Net.Sockets.TcpClient和System.Net.Sockets.Socket都没有直接为Connect/BeginConnect提供超时 ...

  2. 异步和同步http请求超时机制

    异步超时设置: 例子: Example: do a simple HTTP GET request for http://www.nethype.de/ and print the response ...

  3. socket测试远程地址能否连接并为连接设置超时

    public class TestConnect { string hostIp = ""; ; public string recMsg = ""; Sock ...

  4. socket测试远程地址能否连接并为连接设置超时(转)

    public   class TestConnect { string hostIp = ""; int port = 3314; public string recMsg = & ...

  5. 从报错“无效操作,连接被关闭”探究Transaction的Timeout超时机制

    1.报错如下:Invalid Operation the connection is closed,无效操作,连接被关闭.这个错误是并不是每次都报,只有在复杂操作.大事务的情况下才偶然报出来. sta ...

  6. C# Socket连接超时设置

    问题描述:         对于C# Socket没有超时设置的选项,默认情况下进行Socket连接,返回连接失败需要20-30s时间,严重影响用户体验 问题解决: Socket服务器端: Socke ...

  7. 一个Socket连接管理池(心跳机制)

    一个Socket连接管理池(心跳机制) http://cuisuqiang.iteye.com/blog/1489661

  8. ES transport client底层是netty实现,netty本质上是异步方式,但是netty自身可以使用sync或者await(future超时机制)来实现类似同步调用!因此,ES transport client可以同步调用也可以异步(不过底层的socket必然是异步实现)

    ES transport client底层是netty实现,netty本质上是异步方式,但是netty自身可以使用sync或者await(future超时机制)来实现类似同步调用! 因此,ES tra ...

  9. c# 创建socket连接辅助类-可指定超时时间

    using AD.SocketForm.Model; using NLog; using System; using System.Net.Sockets; using System.Threadin ...

随机推荐

  1. oracle PL/SQL(procedure language/SQL)程序设计之触发器(trigger)

    创建触发器 触发器类似于过程和函数,都拥有声明.执行和异常处理过程的带名PL/SQL块.与包类似,触发器必须存储在数据库中.前面已经讲过,过程是显式地通过过程调用执行的,同时过程调用可以传递参数.与之 ...

  2. Linux的SOCKET编程详解

    1. 网络中进程之间如何通信 进 程通信的概念最初来源于单机系统.由于每个进程都在自己的地址范围内运行,为保证两个相互通信的进 程之间既互不干扰又协调一致工作,操作系统为进程通信提供了相应设施,如 U ...

  3. hdu 4705 排列组合

    思路:枚举能是A,B,C在一条简单路径上的中点. 计算多少个几何能满足.在用总数减去 #pragma comment(linker, "/STACK:16777216") #inc ...

  4. 4560 NOIP2015 D2T2 子串

    4560 NOIP2015 D2T2 子串  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Description 有两 ...

  5. web前端开发控件学习笔记之jqgrid+ztree+echarts

    版权声明:本文为博主原创文章,转载请注明出处.   作为web前端初学者,今天要记录的是三个控件的使用心得,分别是表格控件jqgrid,树形控件ztree,图表控件echarts.下边分别进行描述. ...

  6. 总结——visibility和display

    最近工作中用到了显示和隐藏——visibility和display,它们两个都有显示隐藏的意思,但是又有所差别,接下来我们先看一下效果吧. 当没有效果的时候,我们展示一下源码 <!DOCTYPE ...

  7. OC Categroy类别

    Categroy类别,又称为扩展类,在类的原基础上扩展方法,且不可添加变量,如果扩展的方法与原始类中的方法相同,则会隐藏原始方法,且不可在扩展方法中通过super调用原始方法,这里与继承不同. 定义: ...

  8. 浅谈我眼中的ASP.NET MVC

    坦白地说,学习MVC是前一段时间的事情了.但是,我当时虽然也实践过,却也不能很好的说出个所以然来.因此,也 一直没敢写点什么文字总结.最近,开始学习EF,也同时在使用MVC来结合EF实践增删改查.慢慢 ...

  9. Cannot find protocol declaration for "XXDelegate" 找不到协议错误

    原因是 在A里面继承了B类里面的"XXDelegate",在B类的头文件里又导入了A类的头文件 解决方法 不在B类的头文件导入A类的头文件,改成在B类的.m文件导入A类的头文件

  10. Part 1 What is AngularJS

    What is AngularJS ? AngularJS is a JavaScirpt framework that helps build web application. AngularJS ...