欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C# Socket连接请求超时机制实现代码分享

程序员文章站 2024-02-19 13:28:34
.net的system.net.sockets.tcpclient和system.net.sockets.socket都没有直接为connect/beginconnect提...

.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 tryconnect(ipendpoint remoteendpoint, int timeoutmilisecond)
    {
        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(timeoutmilisecond, 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();
        }
    }
}