ManageTcp.cs 6.35 KB
using RCS.Model.ClientMoel;
using RCS.Model.Comm;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace RCS.WinClient.TCP
{
    public class ManageTcp
    {
        /// <summary>
        /// 服务侦听
        /// </summary>
        /// <param name="backlog">挂起的连接请求</param>
        /// <param name="svrSocket">服务套接字</param>
        public static void ServerListen(int backlog, Socket svrSocket)
        {
            //用socket对象的Listen()方法开始监听
            svrSocket.Listen(backlog);//开始监听
            while (true)
            {
                //服务器监听,建立socket
                Socket ClientSocket = svrSocket.Accept();
                ClientSocket.ReceiveTimeout = 3000;
                //创建线程
                var thSocket = new Thread(new ParameterizedThreadStart(DealAgvMsg));
                ////线程启动,参数为socket
                thSocket.Start(ClientSocket);
            }
        }

        /// <summary>
        /// 处理AGV消息
        /// </summary>
        /// <param name="clientSocket">客户端对象</param>
        public static void DealAgvMsg(object? socket)
        {
            var clientSocket = socket as Socket;
            if (clientSocket == null)
            {
                return;
            }
            string address = "";
            ClientControl? clientControl = null;
            while (true)
            {
                try
                {
                    Thread.Sleep(50);
                    var ReceiveData = new byte[86];
                    clientSocket.ReceiveTimeout = 3000;
                    //获取客户端连接的IP
                    if (clientSocket.RemoteEndPoint is IPEndPoint ipEndPoint)
                    {
                        address = ipEndPoint.Address.ToString();
                    }
                    //轮询客户端Socket是否能读取
                    if (!clientSocket.Poll(3000000, SelectMode.SelectRead))
                    {
                        continue;
                    }
                    //接收来自客户端的信息
                    int DataLength = clientSocket.Receive(ReceiveData);
                    if (DataLength == 0)
                    {
                        continue;
                    }
                    var socketOpt = new SocketOpt(clientSocket, address, ReceiveData);


                    //如果没有客户端,那就就加入进来,初始化为【未执行】
                    clientControl = App.ClientWork.FirstOrDefault(a => a.ClientIp == address);
                    if (clientControl == null)
                    {
                        clientControl = new ClientControl
                        {
                            ClientIp = address,
                            IsDoing = false
                        };
                        App.ClientWork.Add(clientControl);
                    }

                    //判断该客户端是否还在执行操作,没有执行就修改【执行中】,然后处理后向AGV发送,然后把状态修改为【未执行】
                    if (clientControl.IsDoing)
                        continue;
                    clientControl.IsDoing = true;
                    MsgRecevie.TcpTranslate(socketOpt);
                    if (socketOpt.SendData != null)
                    {
                        //向客户端发送数据
                       Send(socketOpt);
                    }
                    clientControl.IsDoing = false;

                }
                catch (Exception ex)
                {
                    if (clientControl != null)
                    {
                        clientControl.IsDoing = false;
                    }
                    if (!clientSocket.Connected)
                    {
                        clientSocket.Dispose();
                        break;
                    }
                    var msg = $"处理AGV消息失败,地址:{address},原因:{ex.Message},堆栈:{ex.StackTrace}";
                    App.ExFile.MessageError("DealAgvMsg", msg);
                }
                //finally
                //{
                //暂时取消关闭,采用长连接
                //clientSocket?.Close();
                //}
            }
        }

        /// <summary>
        /// Tcp指令发送
        /// </summary>
        /// <param name="clientSocket">自定义Socket对象</param>
        /// <returns>发送结果</returns>
        public static void Send(SocketOpt clientSocket)
        {
            var address = "";
            try
            {
                Socket getSocket = clientSocket.ClientSocket;
                if (getSocket.RemoteEndPoint is IPEndPoint ipEndPoint)
                {
                    address = ipEndPoint.Address.ToString();
                }
                byte[] dataRecv = clientSocket.RecData;
                
                //using (FileStream fileStream = new FileStream($"C:\\Users\\hh\\Desktop", FileMode.OpenOrCreate))
                //{
                //    fileStream.Write(dataRecv, 0, dataRecv.Length);
                //}
                    // 小车编码
                    string strAddress = clientSocket.EquipmentNo ?? "";
                if (clientSocket.SendData != null)
                {
                    getSocket.Send(clientSocket.SendData, clientSocket.SendData.Length, 0);
                   
                    // 如果关机列表中有数据,并且是当前小车,而且是关机指令,那就把AGV状态改为离线。最后从关机列表中移除。
                    if (App.OffAgvNos.Contains(strAddress) && clientSocket.SendData[5] == 21)
                    {
                        var agv = App.AgvList.FirstOrDefault(a => a.AgvNo == strAddress);
                        if (agv != null)
                        {
                            agv.IsOnline = false;
                        }
                        App.OffAgvNos.Remove(strAddress);
                    }
                }
            }
            catch (Exception ex)
            {
                var msg = $"向AGV{clientSocket.EquipmentNo}发送Tcp指令异常,数据长度:【{clientSocket.SendData?.Length}】,地址:【{address}】,原因:【{ex.Message}】,堆栈:【{ex.StackTrace}】";
                App.ExFile.MessageError("Send", msg);
            }
        }
    }
}