C#Socket通信


服务端(监听)

        #region Socket连接
        public Socket socket;//负责通信的socket
        Socket socketWatch;//负责监听的socket
        CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
        bool isConnect = false;
        string ReConnTime = ConfigurationManager.AppSettings["ReConnTime"];
        private void SocketConnect()
        {
            IPAddress ip = IPAddress.Any;
            //创建端口号对象
            IPEndPoint ipe = new IPEndPoint(ip, 1111);
            //创建一个负责监听的socket
            socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //开始监听
            socketWatch.Bind(ipe);
            socketWatch.Listen(1);
            //listen();
            Task.Factory.StartNew(() => { listen(); },cancellationTokenSource.Token);
            //t = new Thread(listen);
            //t.IsBackground = true;//后台运行
            //t.Start();
        }

        private void listen()
        {
            while (!isConnect)//socket通信断开时,循环连接
            {
                listLog.Items.Add($"等待客户端连接...\r\n");
                //等待对方的连接,并且创建一个负责通信的socket
                socket = socketWatch.Accept();
                listLog.Items.Add($"连接成功!\r\n 准备接收数据...");
                isConnect = true;
                while (isConnect)//socket通信连接时,循环接收
                {
                    try
                    {
                        byte[] data = new byte[1024];
                        int recv = socket.Receive(data);
                        string strData = Encoding.UTF8.GetString(data, 0, recv);
                        listLog.Items.Add($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")} 收到数据:{strData}\r\n");
                        if (strData.Contains(","))
                            LaserCode(strData);
                        else
                            listLog.Items.Add($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")} 收到数据出错:{strData}\r\n");
                    }
                    catch (Exception ex)
                    {
                        listLog.Items.Add($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")} 客户端连接断开:{ex.Message}\r\n");
                        //socketWatch.Close();
                        //socket.Close();
                        //cancellationTokenSource.Cancel();
                        //SocketConnect();
                        isConnect = false;
                    }

                }
                Thread.Sleep(int.Parse(ReConnTime));
            }
        }
        #endregion
        /// 
        /// 处理收到的数据
        /// 
        /// 
        private void LaserCode(string data)
        {
            Task.Run(new Action(() =>
            {
                var dataArray = data.Split(',');
                if (int.Parse(dataArray[0]) == 1)
                {
                    //激光刻码
                    //StartLaserCode(dataArray[1]);
                    Thread.Sleep(2000);
                    sendData("OK");
                }
            }));
        }
        /// 
        /// 激光刻码
        /// 
        private void StartLaserCode(string heapCode)
        {
        }

        private void sendData(string info)
        {
            var buffer = Encoding.UTF8.GetBytes(info);
            socket.Send(buffer);
        }

客户端(连接)

 Task.Factory.StartNew(() =>
                {
                    try
                    {
                        //连接目标程序
                        conn();
                    }
                    catch (Exception ex)
                    {
                        _log.Info($"连接激光刻码机失败:{ex.Message}");
                        reConnection();
                    }
                }, TaskCreationOptions.LongRunning);//激光刻码socket


 #region 连接

        Socket mySocket;
        string strIP;// ConfigurationManager.AppSettings["ip"];
        int port;// ConfigurationManager.AppSettings["port"];
        //bool IsConnectAgv = false;
        CancellationTokenSource sendCancellationTokenSource;
        CancellationTokenSource receiveCancellationTokenSource;
        public bool ConnStatus = false;

        /// 
        /// 连接
        /// 
        private void conn()
        {
            var MarkEzdInfo = basPLCDAL.GetSignal(x => x.PlcName == "MarkEzd");
            sendCancellationTokenSource = new CancellationTokenSource();
            receiveCancellationTokenSource = new CancellationTokenSource();
            mySocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            //读取配置文件,获取目标程序的IP与端口号
            strIP = MarkEzdInfo.IPAddress;
            port = MarkEzdInfo.IPPort;
            IPAddress ip = IPAddress.Parse(strIP);
            IPEndPoint ipe = new IPEndPoint(ip, port);
            //连接目标程序
            mySocket.Connect(ipe);
            ConnStatus = true;
            _log.Info($"连接激光打码机成功!");
            Task.Run(() =>
            {
                sendData("1,123456789");
            }, sendCancellationTokenSource.Token);

            Task.Run(() =>
            {
                receiveData();
            }, receiveCancellationTokenSource.Token);

        }
        #endregion
        #region 接收数据
        /// 
        /// 接收数据
        /// 
        private void receiveData()
        {
            try
            {
                while (ConnStatus)
                {

                    var receiveByte = new byte[1024];
                    int r = mySocket.Receive(receiveByte);
                    if (r == 0)
                    {
                        break;
                    }
                    var receiveData = Encoding.UTF8.GetString(receiveByte, 0, r);
                    _log.Info($"收到激光刻码机反馈:{receiveData}\r\n");

                }
            }
            catch (Exception ex)
            {
                _log.Info($"接收激光刻码机数据异常:{ex.Message}\r\n");
                if (!mySocket.Connected)
                {
                   
                    _log.Info($"激光刻码机连接断开,尝试重连...\r\n");
                    CloseCurrentConn();
                    receiveCancellationTokenSource.Cancel();
                    sendCancellationTokenSource.Cancel();
                    reConnection();
                }
            }
        }


        #endregion

        #region 发送数据
        private void sendData(object signal)
        {
            while (true)
            {
                var buffer = Encoding.UTF8.GetBytes(signal.ToString());
                mySocket.Send(buffer);
                Thread.Sleep(5000);
            }
        }
        #endregion

        #region 关闭连接
        /// 
        /// 关闭当前socket连接
        /// 
        public void CloseCurrentConn()
        {
            //mySocket.Shutdown(SocketShutdown.Both);
            //mySocket.Disconnect(true);
            ConnStatus = false;
            mySocket.Close();

        }
        #endregion

        #region 重连
        /// 
        /// 重连
        /// 
        private void reConnection()
        {
            var MarkEzdInfo = basPLCDAL.GetSignal(x => x.PlcName == "MarkEzd");
            var ReConnTime = MarkEzdInfo.PLCTimeout;
            int count = 0;
            while (!ConnStatus)
            {
                count++;
                try
                {
                    conn();

                    _log.Info($"第{count}次重连激光刻码机,成功!\r\n");
                }
                catch (Exception ex)
                {
                    _log.Info($"第{count}次重连激光刻码机失败:{ex.Message}\r\n");
                }
                Thread.Sleep(ReConnTime);
            }
        }
        #endregion