• C# socket 连接超时代码实现


    在写 C# socket 的时候发现 socket 连接无法设置超时时间,需要15s才能超时返回。百度一下发现也没有实现的比较好的代码。

    因此,才有了下面这段 socket 连接超时的代码,这段代码已经应用到实际的项目中,并且运行稳定。

    如果你有更好的实现方案可以给我留言。

        class Socket2 : IComunication
        {
            static IPEndPoint ipe;
    
            static byte[] sendBytes = new byte[1400];
            static byte[] recBytes = new byte[1400];
    
            volatile static Socket socket = null;
    
            static System.Threading.Timer readTimer = null;
            static int readOverTime;
            static bool ReadOK;
            static System.Threading.Timer connectTimer = null;
            static int connectOverTime;
    
            public Socket2()
            {
                readTimer = new System.Threading.Timer(OnReadTimeUp, null, Timeout.Infinite, Timeout.Infinite);
    
                object obj = Global.Config.Read("ReadOverTime");
                if (obj == null || !int.TryParse(obj.ToString(), out readOverTime))
                {
                    readOverTime = 3000;
                }
    
                obj = Global.Config.Read("ConnectOverTime");
                if (obj == null || !int.TryParse(obj.ToString(), out connectOverTime))
                {
                    connectOverTime = 3000;
                }
            }
    
    
            private static void OnConnectTimeUp(object obj)
            {
                StateObject stateObject = (StateObject)obj;
                lock (connectTimer)
                {
                    if (stateObject.socket != null)
                    {
                        stateObject.socket.Close();
                        stateObject.socket = null;
                        socket = null;
                    }
                }
            }
    
            private static void OnReadTimeUp(object obj)
            {
                ReadOK = false;
                socket.Close();
            }
    
            public bool Start()
            {
                try
                {
                    if (socket == null)
                    {
                        string host = Global.Config.Read("DriverIP").ToString();
                        int port = Convert.ToInt32(Global.Config.Read("DriverPort"));
                        IPAddress ip = IPAddress.Parse(host);
                        ipe = new IPEndPoint(ip, port);
    
                        socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    
                        socket.DontFragment = false;
                        socket.ExclusiveAddressUse = true;
                        socket.UseOnlyOverlappedIO = false;
                        socket.SendBufferSize = 1500;
                        socket.ReceiveBufferSize = 1500;
                        socket.ReceiveTimeout = readOverTime;
                        socket.SendTimeout = readOverTime;
                        // 设置连接超时计时器
                        StateObject so = new StateObject();
                        so.socket = socket;
    
                        //socket.Connect(ipe);
                        connectTimer = new System.Threading.Timer(OnConnectTimeUp, so, Timeout.Infinite, Timeout.Infinite);
                        connectTimer.Change(connectOverTime, Timeout.Infinite);
                        socket.BeginConnect(ipe, new AsyncCallback(ConnectCallback), so);
                        autoEventConnect.WaitOne();
                    }
                    return true;
                }
                catch (SocketException e)
                {
                    Global.log.Debug(e);
                    socket.Close();
                    socket = null;
                    return false;
                }
                catch (Exception e)
                {
                    if (socket != null)
                    {
                        socket.Close();
                    }
                    socket = null;
                    return false;
                }
            }
    
            AutoResetEvent autoEventConnect = new AutoResetEvent(false);
    
            private void ConnectCallback(IAsyncResult ar)
            {
                // Retrieve the socket from the state object.
                StateObject stateObject = (StateObject)ar.AsyncState;
                lock (connectTimer)
                {
                    try
                    {
                        if (stateObject.socket != null)
                        {
                            // Complete the connection.
                            stateObject.socket.EndConnect(ar);
    
                            connectTimer.Change(Timeout.Infinite, Timeout.Infinite);
                            connectTimer.Dispose();
                        }
                    }
                    catch (Exception e)
                    {
                        if (stateObject.socket != null)
                        {
                            stateObject.socket.Close();
                        }
                        stateObject.socket = null;
                        stateObject.reciveBuffer = null;
                        stateObject.sendBuffer = null;
                        stateObject = null;
                    }
                }
                autoEventConnect.Set();
            }
    
    
            public bool Stop()
            {
                if (socket != null)
                {
                    socket.Close();
                }
                socket = null;
                return true;
            }
    
            public bool Write()
            {
                try
                {
                    if (socket != null)
                    {
                        buildSendBytes();
                        socket.NoDelay = true;
                        int n = socket.Send(sendBytes, sendBytes.Length , SocketFlags.None);
                        if (n != sendBytes.Length)
                        {
                            Global.log.Debug("send error 需要发送的字节数 " + "实际发送的字节数" + sendBytes.Length + ":" +n);
                        }
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
                catch (Exception e)
                {
                    Global.log.Debug("Error Send");
                    Global.log.Debug(e);
                    if (socket != null)
                    {
                        socket.Close();
                        socket = null;
                    }
                    return false;
                }
            }
    
            public bool Read()
            {
                try
                {
                    if (socket != null)
                    {
                        StateObject so = new StateObject();
    
                        so.socket = socket;
                        so.reciveBuffer = recBytes;
                        // 设置读超时计时器
                        readTimer.Change(readOverTime, Timeout.Infinite);
    
                        socket.BeginReceive(recBytes, 0, recBytes.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), so);
                        // 接受完成
                        autoEvent.WaitOne();
                        readTimer.Change(Timeout.Infinite, Timeout.Infinite);
                        buildRecBytes();
                        // 需要添加读超时返回 false
                        if (ReadOK == true)
                        {
                            return true;
                        }
                        else
                        {
                            return false;
                        }
                    }
                    else
                    {
                        return false;
                    }
                }
                catch (Exception e)
                {
                    Global.log.Debug(e);
                    return false;
                }
            }
    
            AutoResetEvent autoEvent = new AutoResetEvent(false);
    
            public class StateObject
            {
                public Socket socket = null;
                public byte[] reciveBuffer = null;
                public byte[] sendBuffer = null;
            }
    
            volatile int bytesRecieved = 0;
    
            public void ReceiveCallback(IAsyncResult ar)
            {
                StateObject state = null;
                try
                {
                    // Retrieve the state object and the client socket 
                    // from the asynchronous state object.
                    state = (StateObject)ar.AsyncState;
    
                    // Read data from the remote device.
                    int bytesRead = state.socket.EndReceive(ar);
                    if (bytesRead > 1400)
                    {
                        Global.log.Debug("bytesRead > 1400 :" + bytesRead);
                    }
                    if (bytesRead > 0)
                    {
                        bytesRecieved += bytesRead;
                        if (bytesRecieved < recBytes.Length)
                        {
                            state.socket.BeginReceive(state.reciveBuffer, bytesRecieved, state.reciveBuffer.Length - bytesRecieved, SocketFlags.None, new AsyncCallback(ReceiveCallback), state);
                        }
                        if (bytesRecieved == recBytes.Length)
                        {
                            bytesRecieved = 0;
                            ReadOK = true;
                            autoEvent.Set();
                        }
                    }
                    else
                    {
                        state.socket.Close();
                        state.socket = null;
                        socket = null;
                        state.reciveBuffer = null;
                        state.sendBuffer = null;
                        state = null;
                        ReadOK = false;
                        autoEvent.Set();
                    }
    
                }
                catch (Exception e)
                {
                    Global.log.Debug("Error Recieve");
                    Global.log.Debug(e);
                    if (state.socket != null)
                    {
                        state.socket.Close();
                        state.socket = null;
                        socket = null;
                    }
    
                    state.reciveBuffer = null;
                    state.sendBuffer = null;
                    state = null;
                    ReadOK = false;
                    autoEvent.Set();
                }
            }
    
            public bool ReadArray()
            {
                throw new NotImplementedException();
            }
    
            public bool WriteArray()
            {
                throw new NotImplementedException();
            }
        }
    
  • 相关阅读:
    合并区间
    编程团体赛
    寻找数组的中间位置
    翻转链表2
    链表翻转
    CF1237H. Balanced Reversals
    arc108E
    agc028D
    CF1446D. Frequency Problem
    CF1439D. INOI Final Contests
  • 原文地址:https://www.cnblogs.com/flysun027/p/13726918.html
Copyright © 2020-2023  润新知