SYL il y a 4 ans
Parent
commit
afdbe28d35

+ 1 - 1
DWZB_Agv_Agreement/App.config

@@ -4,7 +4,7 @@
 		<!--Socket服务端 连接方式 Udp、Tcp-->
 		<add key="SocketServerConnType" value="Tcp" />
 		<!--Socket服务端 IP地址-->
-		<add key="SocketServerIpAddress" value="192.168.5.156" />
+		<add key="SocketServerIpAddress" value="192.168.5.194" />
 		<!--Socket服务端 端口号-->
 		<add key="SocketServerPort" value="10001"/>
 		<!--AGV编号-->

+ 13 - 0
DWZB_Agv_Agreement/Form1.Designer.cs

@@ -49,6 +49,7 @@ namespace DWZB_Agv_Agreement
             this.label4 = new System.Windows.Forms.Label();
             this.numericUpDown2 = new System.Windows.Forms.NumericUpDown();
             this.button11 = new System.Windows.Forms.Button();
+            this.button12 = new System.Windows.Forms.Button();
             ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).BeginInit();
             ((System.ComponentModel.ISupportInitialize)(this.numericUpDown2)).BeginInit();
             this.SuspendLayout();
@@ -278,11 +279,22 @@ namespace DWZB_Agv_Agreement
             this.button11.UseVisualStyleBackColor = true;
             this.button11.Click += new System.EventHandler(this.button11_Click);
             // 
+            // button12
+            // 
+            this.button12.Location = new System.Drawing.Point(666, 167);
+            this.button12.Name = "button12";
+            this.button12.Size = new System.Drawing.Size(125, 30);
+            this.button12.TabIndex = 12;
+            this.button12.Text = "关闭调度服务监控";
+            this.button12.UseVisualStyleBackColor = true;
+            this.button12.Click += new System.EventHandler(this.button12_Click);
+            // 
             // Form1
             // 
             this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F);
             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
             this.ClientSize = new System.Drawing.Size(934, 605);
+            this.Controls.Add(this.button12);
             this.Controls.Add(this.button11);
             this.Controls.Add(this.textBox1);
             this.Controls.Add(this.button10);
@@ -335,6 +347,7 @@ namespace DWZB_Agv_Agreement
         private System.Windows.Forms.Label label4;
         private System.Windows.Forms.NumericUpDown numericUpDown2;
         private System.Windows.Forms.Button button11;
+        private System.Windows.Forms.Button button12;
     }
 }
 

+ 19 - 5
DWZB_Agv_Agreement/Form1.cs

@@ -53,12 +53,15 @@ namespace DWZB_Agv_Agreement
                 socketServerMd.CloseEvent += new GetCloseEventHandler(Socket_CloseEvent);
                 //开启监听
                 socketServerMd.StartListen(AppConfigHelper.Get("SocketServerIpAddress"), Convert.ToInt32(AppConfigHelper.Get("SocketServerPort")));
-                Thread thCodeScanner = new Thread(socketServerMd.ListeneSocketClientConnectAccept)
-                {
-                    IsBackground = true
-                };
-                thCodeScanner.Start();
+                socketServerMd.StartListenClientAccept();
+
+                //Thread thCodeScanner = new Thread(socketServerMd.ListeneSocketClientConnectAccept)
+                //{
+                //    IsBackground = true
+                //};
+                //thCodeScanner.Start();
                 button1.Enabled = false;
+                button12.Enabled = true;
             }
             catch (Exception ex)
             {
@@ -536,5 +539,16 @@ namespace DWZB_Agv_Agreement
             //验证
             return Regex.IsMatch(ip, pattern);
         }
+
+        private void button12_Click(object sender, EventArgs e)
+        {
+            socketServerMd.CloseServer();
+            socketServerMd.MessageEvent -= new GetMessageEventHandler(Socket_MessageEvent);
+            socketServerMd.AcceptEvent -= new GetAcceptEventHandler(Socket_AcceptEvent);
+            socketServerMd.CloseEvent -= new GetCloseEventHandler(Socket_CloseEvent);
+            comboBox1.Items.Clear();
+            button12.Enabled = false;
+            button1.Enabled = true;
+        }
     }
 }

+ 138 - 36
DWZB_Agv_Agreement/SocketServerHelper.cs

@@ -1,6 +1,7 @@
 using System;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
+using System.ComponentModel;
 using System.Linq;
 using System.Net;
 using System.Net.Sockets;
@@ -10,34 +11,18 @@ using System.Threading.Tasks;
 
 namespace DWZB_Agv_Agreement
 {
-
-    #region 定义委托、事件
-    /// <summary>
-    /// 获取消息委托
-    /// </summary>
-    /// <param name="sender">消息主体buffer</param>
-    /// <param name="ip">ip</param>
-    /// <param name="dataLength">数据长度</param>
-    /// <param name="e">事件类对象</param>
-    public delegate void GetMessageEventHandler(object sender, string ip, int dataLength, EventArgs e);
-    /// <summary>
-    /// 获取链接委托
-    /// </summary>
-    /// <param name="sender">链接进入的IP</param>
-    /// <param name="e">事件类对象</param>
-    public delegate void GetAcceptEventHandler(object sender, EventArgs e);
-    /// <summary>
-    /// 关闭链接委托
-    /// </summary>
-    /// <param name="sender">链接进入的IP</param>
-    /// <param name="e">事件类对象</param>
-    public delegate void GetCloseEventHandler(object sender, EventArgs e);
-    #endregion
-
     public class SocketServerHelper
     {
 
-        #region 事件
+        #region 自定义事件
+        /// <summary>
+        /// 获取消息委托
+        /// </summary>
+        /// <param name="sender">消息主体buffer</param>
+        /// <param name="ip">ip</param>
+        /// <param name="dataLength">数据长度</param>
+        /// <param name="e">事件类对象</param>
+        public delegate void GetMessageEventHandler(object sender, string ip, int dataLength, EventArgs e);
         public event GetMessageEventHandler MessageEvent;
         /// <summary>
         /// 触发接收到Socket客户端消息的委托事件
@@ -51,6 +36,13 @@ namespace DWZB_Agv_Agreement
             MessageEvent?.Invoke(sender, ip, dataLength, e);
         }
 
+
+        /// <summary>
+        /// 获取链接委托
+        /// </summary>
+        /// <param name="sender">链接进入的IP</param>
+        /// <param name="e">事件类对象</param>
+        public delegate void GetAcceptEventHandler(object sender, EventArgs e);
         public event GetAcceptEventHandler AcceptEvent;
         /// <summary>
         /// 触发Socket客户接入服务端的委托事件
@@ -62,6 +54,12 @@ namespace DWZB_Agv_Agreement
             AcceptEvent?.Invoke(sender, e);
         }
 
+        /// <summary>
+        /// 关闭链接委托
+        /// </summary>
+        /// <param name="sender">链接进入的IP</param>
+        /// <param name="e">事件类对象</param>
+        public delegate void GetCloseEventHandler(object sender, EventArgs e);
         public event GetCloseEventHandler CloseEvent;
         /// <summary>
         /// 触发关闭链接委托事件
@@ -81,17 +79,17 @@ namespace DWZB_Agv_Agreement
         /// </summary>
         public Socket SocketServerListen;
         /// <summary>
+        /// Socket服务端监控可取消线程对象
+        /// </summary>
+        public BackgroundWorker SocketServerThWorker;
+        /// <summary>
         /// Socket客户端套接字对象字典
         /// </summary>
         public ConcurrentDictionary<string, Socket> dicSockClientList = new ConcurrentDictionary<string, Socket>();
         /// <summary>
         /// Socket客户端接收数据线程字典
         /// </summary>
-        //public ConcurrentDictionary<string, Thread> dicSockThreadList = new ConcurrentDictionary<string, Thread>();
-        /// <summary>
-        /// 监听客户端连接的线程标识
-        /// </summary>
-        private bool Flag_Listen = false;
+        public ConcurrentDictionary<string, BackgroundWorker> dicSockThreadWorkerList = new ConcurrentDictionary<string, BackgroundWorker>();
         #endregion
 
         #region 方法
@@ -116,7 +114,6 @@ namespace DWZB_Agv_Agreement
                 //设置监听队列
                 SocketServerListen.Listen(100);
                 LogHelper.WriteLog($"Socket服务端 ip地址:【{ip}】端口号:【{port}】 开启监听成功!", LogTypeEnum.SocketRun);
-                Flag_Listen = true;
             }
             catch (Exception ex)
             {
@@ -176,12 +173,94 @@ namespace DWZB_Agv_Agreement
         //}
         #endregion
 
+        public void StartListenClientAccept()
+        {
+            SocketServerThWorker = new BackgroundWorker
+            {
+                WorkerReportsProgress = true,
+                WorkerSupportsCancellation = true
+            };
+            SocketServerThWorker.DoWork += (object sender, DoWorkEventArgs e) => {
+                while (true)
+                {
+                    if (SocketServerThWorker.CancellationPending)
+                    {
+                        e.Cancel = true;
+                        return;
+                    }
+                    try
+                    {
+                        Socket newSoket = SocketServerListen.Accept();
+                        string ipAddress = newSoket.RemoteEndPoint.ToString();
+                        BackgroundWorker ThWorkerMd = new BackgroundWorker
+                        {
+                            WorkerReportsProgress = true,
+                            WorkerSupportsCancellation = true
+                        };
+                        ThWorkerMd.DoWork += (object sender, DoWorkEventArgs e) => {
+                            Socket newSocket = e.Argument as Socket;//转成对应的Socket类型
+                            string IPPortID = newSocket.RemoteEndPoint.ToString();//这个线程ID
+                            while (true)
+                            {
+                                if (ThWorkerMd.CancellationPending)
+                                {
+                                    e.Cancel = true;
+                                    break;
+                                }
+                                byte[] buffer = new byte[1024 * 2];
+                                int receiveLength;
+                                try  //由于Socket中的Receive方法容易抛出异常,所以我们在这里要捕获异常。
+                                {
+                                    bool a = dicSockClientList[IPPortID].Poll(10, SelectMode.SelectRead);
+                                    receiveLength = dicSockClientList[IPPortID].Receive(buffer);//接收从客户端发送过来的数据
+                                    if (a)
+                                    {
+                                        LogHelper.WriteLog($"Socket客户端:【{IPPortID}】主动断开连接,Socket服务端准备移除该客户端连接!", LogTypeEnum.SocketErr);
+                                        //触发Socket客户端断开连接实践
+                                        OnCloseEvent(IPPortID, EventArgs.Empty);
+                                        break;
+                                    }
+                                }
+                                catch (Exception ex)
+                                {
+                                    LogHelper.WriteLog($"Socket客户端:【{IPPortID}】数据接受发生异常:【{ex.Message}】,Socket服务端已经移除该客户端连接!", LogTypeEnum.SocketErr);
+                                    //触发Socket客户端断开连接实践
+                                    OnCloseEvent(IPPortID, EventArgs.Empty);
+                                    break;
+                                }
+                                if (receiveLength > 0)
+                                {
+                                    //记录接收到的原始数据                    
+                                    LogHelper.WriteLog($"Socket客户端:【{IPPortID}】接收到:【{receiveLength}】字节数据,数据内容:【{BitConverter.ToString(buffer, 0, receiveLength)}】。", LogTypeEnum.SocketData);
+                                    //触发接收到Socket客户端发送数据的事件
+                                    OnNewMessage(buffer, IPPortID, receiveLength, EventArgs.Empty);
+                                }
+                            }
+                        };
+                        ThWorkerMd.RunWorkerAsync(newSoket);
+
+                        dicSockClientList.TryAdd(ipAddress, newSoket);
+                        dicSockThreadWorkerList.TryAdd(ipAddress, ThWorkerMd);
+                        //触发Socket客户端接入服务端事件
+                        OnAcceptEvent(ipAddress, EventArgs.Empty);
+
+                        LogHelper.WriteLog($"Socket客户端:【{ipAddress}】连接成功!", LogTypeEnum.SocketRun);
+                    }
+                    catch (Exception ex)
+                    {
+                        LogHelper.WriteLog($"Socket服务端监听客户端的连接的函数发生异常:【{ex.Message}】", LogTypeEnum.SocketErr);
+                    }
+                }
+            };
+            SocketServerThWorker.RunWorkerAsync();
+        }
+
         /// <summary>
         /// 循环监听客户端的连接
         /// </summary>
         public void ListeneSocketClientConnectAccept()
         {
-            while (Flag_Listen)
+            while (true)
             {
                 try
                 {
@@ -218,7 +297,7 @@ namespace DWZB_Agv_Agreement
             Socket newSocket = socket as Socket;//转成对应的Socket类型
             string IPPortID = newSocket.RemoteEndPoint.ToString();//这个线程ID
 
-            while (Flag_Listen)
+            while (true)
             {
                 byte[] buffer = new byte[1024 * 2];
                 int receiveLength;
@@ -256,21 +335,40 @@ namespace DWZB_Agv_Agreement
         /// </summary>
         public void CloseServer()
         {
+            if (SocketServerThWorker.IsBusy)
+            {
+                SocketServerThWorker.CancelAsync();
+            }
+
+            lock (dicSockThreadWorkerList)
+            {
+                foreach (var item in dicSockThreadWorkerList)
+                {
+                    if (item.Value.IsBusy)
+                    {
+                        item.Value.CancelAsync();
+                    }
+                }
+                dicSockThreadWorkerList.Clear();//清除字典
+            }
+
             lock (dicSockClientList)
             {
                 foreach (var item in dicSockClientList)
                 {
+                    item.Value.Disconnect(true);
                     item.Value.Close();//关闭每一个连接
                 }
                 dicSockClientList.Clear();//清除字典
             }
-            Flag_Listen = false;
-            //服务端不能主动关闭连接,需要把监听到的连接逐个关闭
-            SocketServerListen.Shutdown(SocketShutdown.Both);
+
             if (SocketServerListen != null)
             {
                 SocketServerListen.Close();
+                SocketServerListen.Dispose();
+                //SocketServerListen = null;
             }
+            SocketServerThWorker.Dispose();
         }
 
         public void SendData(string ipAddress,byte[] btArr)
@@ -280,7 +378,11 @@ namespace DWZB_Agv_Agreement
 
         public void RemoveSocketClient(string ipAddress)
         {
+            dicSockClientList[ipAddress].Disconnect(true);
+            dicSockClientList[ipAddress].Close();//关闭每一个连接
             dicSockClientList.TryRemove(ipAddress, out _);
+            dicSockThreadWorkerList[ipAddress].CancelAsync();
+            dicSockThreadWorkerList.TryRemove(ipAddress, out _);
         }
         #endregion