C#Socket开发“网络连接超时设置Timeout”,解决网络连接速度过慢的问题

来源:互联网 发布:python 线程池 编辑:程序博客网 时间:2024/04/29 11:53

      近日,在进行PPC下的网络通讯程序开发时,当服务器的网络中断或连接异常时,客户端在进行TCP连接请求时“Socket.Connect()”速度明显过慢,通常20-30S才能有异常返回。.Net的System.Net.Sockets.TcpClient和System.Net.Sockets.Socket都没有直接为Connect/BeginConnect提供超时控制机制。因此,当服务器未处于监听状态,或者发生网络故障时,客户端连接请求会被迫等待很长一段时间,直到抛出异常。为解决这一问题,我查阅了部分资料同时进行了测试,现将解决方法整理如下:

     

1、部分代码段:

private ManualResetEvent connectDone = new ManualResetEvent(false);

 

private void ConnectCallback(IAsyncResult ar)
{
    try
    {
        Socket client = (Socket) ar.AsyncState;
        client.EndConnect(ar);
       
    }
    catch (Exception e)
    {
        OnErrorEvent(new ErrorEventArgs(e));
    }
    finally
    {
        connectDone.Set();
    }
}

 

 

        /// <summary>
        /// 开始连接的方法
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        /// <param name="selfIP"></param>
        /// <param name="selfPort"></param>
        /// <returns></returns>
        public bool ClientConnect(IPAddress ip, string port, string selfIP, string selfPort)
        {
            try
            {
                IPEndPoint remoteEP = new IPEndPoint(ip, Int32.Parse(port));////网络端点表示为 IP 地址和端口号

                //TCP连接
                clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                //开始连接

                connectDone.Reset();
                clientSocket.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), clientSocket);
                connectDone.WaitOne(5000, false);//等待5秒

                //连接成功
                if (clientSocket.Connected)
                {

                    //do something

                }
                return true;

            }
            catch (Exception)
            {

                return false;
            }
        }

 

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

 

经过测试上面只是解决了连接速度慢的问题(网络异常时),设备可以在连接中断后自动重新连接服务器。但是,我发现当连接不正常时,clientSocket.BeginConnect得到的Socket的Connected属性仍为true,所以要想确保连接的可靠性只能采用信息交互的方式(即客户端向服务端发送要求反馈的信息,并能成功接收到反馈信息时才是正常的连接)。

原创粉丝点击