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

作者:RazanPaul
译者:Todd Wei

原文:http://www.codeproject.com/KB/IP/TimeOutSocket.aspx
转自:http://hi.baidu.com/wf_studio/blog/item/d0a339f4c70c9ae57609d7c9.html

介绍
您可能注意到了,.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。






  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
前 言 6 第1章 进程、线程与网络协议 7 1.1 进程和线程 7 1.1.1 Process类 7 1.1.2 Thread类 9 1.1.3 在一个线程中操作另一个线程的控件 13 1.2 IP地址与端口 15 1.2.1 TCP/IP网络协议 16 1.2.2 IPAddress类与Dns类 17 1.2.3 IPHostEntry类 17 1.2.4 IPEndPoint类 17 1.3 套接字 19 1.3.1 Socket类 20 1.3.2 面向连接的套接字 21 1.3.3 无连接的套接字 23 1.4 网络流 24 1.5 习题1 25 第2章 TCP应用编程 27 2.1 同步TCP应用编程 28 2.1.1 使用套接字发送和接收数据 28 2.1.2 使用NetworkStream对象发送和接收数据 30 2.1.3 TcpClient与TcpListener类 31 2.1.4 解决TCP协议的无消息边界问题 33 2.2 利用同步TCP编写网络游戏 34 2.2.1 服务器端编程 34 2.2.2 客户端编程 49 2.3 异步TCP应用编程 66 2.3.1 EventWaitHandle类 67 2.3.2 AsyncCallback委托 69 2.3.3 BeginAcceptTcpClient方法和EndAcceptTcpClient方法 70 2.3.4 BeginConnect方法和EndConnect方法 70 2.3.5 发送数据 71 2.3.6 接收数据 72 2.4 异步TCP聊天程序 73 2.4.1 服务器端设计 73 2.4.2 客户端设计 79 2.5 习题2 83 第3章 UDP应用编程 84 3.1 UDP协议基础知识 84 3.2 UDP应用编程技术 84 3.2.1 UdpClient类 84 3.2.2 发送和接收数据的方法 86 3.3 利用UDP协议进行广播和组播 90 3.3.1 通过Internet实现群发功能 90 3.3.2 在Internet上举行网络会议讨论 96 3.4 习题3 101 第4章 P2P应用编程 102 4.1 P2P基础知识 102 4.2 P2P应用举例 104 4.3 习题4 114 第5章 SMTP与POP3应用编程 115 5.1 通过应用程序发送电子邮件 115 5.1.1 SMTP协议 115 5.1.2 发送邮件 116 5.2 利用同步TCP接收电子邮件 120 5.2.1 POP3工作原理 121 5.2.2 邮件接收处理 123 5.3 习题5 127 第6章 网络数据加密与解密 128 6.1 对称加密 128 6.2 不对称加密 133 6.3 通过网络传递加密数据 136 6.4 Hash算法与数字签名 152 6.5 习题6 153 第7章 三维设计与多媒体编程 154 7.1 简单的3D设计入门 154 7.2 DirectX基础知识 160 7.2.1 左手坐标系与右手坐标系 160 7.2.2 设备 160 7.2.3 顶点与顶点缓冲 161 7.2.4 Mesh对象 162 7.2.5 法线 162 7.2.6 纹理与纹理映射 162 7.2.7 世界矩阵、投影矩阵与视图矩阵 162 7.2.8 背面剔除 164 7.3 Primitive 164 7.4 Mesh 171 7.5 灯光与材质 177 7.6 音频与视频 187 7.7 直接使用SoundPlayer类播放WAV音频文件 191 7.8 习题7 193 第8章 上机实验指导 194 8.1 实验一 简单网络聊天系统 194 8.2 实验二 网络呼叫应答提醒系统 195 8.3 实验三 文件数据加密与解密 199

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值