Browse Source

update socket server

yhluo 1 month ago
parent
commit
a634c483ad

+ 408 - 220
UAS_MES_HYSX/FunctionCode/Make/Make_ListenSocket.cs

@@ -1,4 +1,5 @@
-using System;
+using Newtonsoft.Json;
+using System;
 using System.Collections.Generic;
 using System.ComponentModel;
 using System.Data;
@@ -12,8 +13,8 @@ using System.Threading;
 using System.Threading.Tasks;
 using System.Web.Services.Description;
 using System.Windows.Forms;
-using UAS_MES_NEW.Entity;
 using UAS_MES_NEW.DataOperate;
+using UAS_MES_NEW.Entity;
 
 namespace UAS_MES_NEW.Make
 {
@@ -28,25 +29,18 @@ namespace UAS_MES_NEW.Make
         DataTable dt;
         DataHelper dh;
 
-        SocketHandle client;
-        string saveFile, sendFile;
+        private SocketServer _server;
+        private int currCount = 0;
 
         private void Make_ListenSocket_Load(object sender, EventArgs e)
         {
             dh = SystemInf.dh;
 
-            string currentPath = Directory.GetParent(AppDomain.CurrentDomain.BaseDirectory).FullName;
-            saveFile = Path.Combine(currentPath, $"Received.txt");
-            sendFile = Path.Combine(currentPath, $"Send.txt");
+            _server = new SocketServer();
+            _server.ReceivedDatas += SocketServer_ReceivedDatas;
+            _server.ReceivedMsg += SocketServer_ReceivedMsg;
 
-            if (!File.Exists(saveFile))
-            {
-                File.Create(saveFile).Dispose();
-            }
-            if (!File.Exists(sendFile))
-            {
-                File.Create(sendFile).Dispose();
-            }
+            IpPort.Text = "127.0.0.1:9979";
         }
 
         private void Connet_Click(object sender, EventArgs e)
@@ -61,7 +55,7 @@ namespace UAS_MES_NEW.Make
             }
         }
 
-        private async void Start_Click(object sender, EventArgs e)
+        private void Start_Click(object sender, EventArgs e)
         {
             if (string.IsNullOrEmpty(IpPort.Text))
             {
@@ -71,58 +65,108 @@ namespace UAS_MES_NEW.Make
 
             string ip = IpPort.Text.Split(':')[0];
             int port = int.Parse(IpPort.Text.Split(':')[1]);
-            client = new SocketHandle(ip, port);
-
-            client.OnFileReceived += OnFileReceived;
-            client.OnMessageReceived += OnMessageReceived;
-            client.OnConnectionStatusChanged += OnConnectionStatusChanged;
+            IPAddress ipAddress = IPAddress.Parse(ip);
 
             if (Start.Text == "开启监听")
             {
                 Start.Text = "关闭监听";
-                IpPort.Enabled = true;
-                client.Close();
+                IpPort.Enabled = false;
+
+                string result = _server.Start(ipAddress, port, 10);
+                ShowMsg(result.StartsWith("OK") ? 1 : 0, result);
             }
             else if (Start.Text == "关闭监听")
             {
                 Start.Text = "开启监听";
-                IpPort.Enabled = false;
-
-                string msg = await client.ConnectAsync();
-                if (!msg.StartsWith("OK"))
-                {
-                    ShowMsg(0, msg);
-                }
-                ShowMsg(1, msg);
+                IpPort.Enabled = true;
 
-                msg = await client.ReceiveFileAsync(saveFile);
-                if (!msg.StartsWith("OK"))
+                if (_server != null)
                 {
-                    ShowMsg(0, msg);
+                    string result = _server.Stop();
+                    ShowMsg(result.StartsWith("OK") ? 1 : 0, result);
                 }
-                ShowMsg(1, msg);
             }
         }
-
-        private async void OnFileReceived(string fileName, string savePath)
+        private void SocketServer_ReceivedDatas(object sender, ReceivedDatasEventArgs e)
         {
-            ShowMsg(1, "文件接收完成: " + fileName + " 保存到: " + savePath);
-            string msg = await client.SendFileAsync(sendFile);
-            if (msg.StartsWith("NG"))
+            this.Invoke(new Action(() =>
             {
-                ShowMsg(0, msg);
-            }
-            ShowMsg(1, "文件发送成功");
-        }
+                currCount += 1;
 
-        private void OnMessageReceived(string message)
-        {
-            ShowMsg(1, "收到服务器消息: " + message);
-        }
+                ShowMsg(1, $"第{currCount}次接收,收到来自 {e.ClientId} 的消息: {e.Message}");
 
-        private void OnConnectionStatusChanged(string status)
+                VerifyResultMessage message = new VerifyResultMessage
+                {
+                    Name = "VerifyResult",
+                    Data = new VerifyResultData
+                    {
+                        ErrorCode = "0",
+                        ErrorMsg = "",
+                        Serial = "BG7349116"
+                    }
+                };
+                string jsonMessage = JsonConvert.SerializeObject(message, Formatting.None);
+
+                string sendMsg = _server.SendMessage(e.ClientId, jsonMessage);
+
+                ShowMsg(sendMsg.StartsWith("OK") ? 1 : 0, sendMsg);
+
+                #region
+                //if (currCount == 1)
+                //{
+                //    VerifyResultMessage message = new VerifyResultMessage
+                //    {
+                //        Name = "VerifyResult",
+                //        Data = new VerifyResultData
+                //        {
+                //            ErrorCode = "0",
+                //            ErrorMsg = "",
+                //            Serial = "BG7349116"
+                //        }
+                //    };
+                //    string jsonMessage = JsonConvert.SerializeObject(message, Formatting.None);
+
+                //    string sendMsg = _server.SendMessage(e.ClientId, jsonMessage);
+
+                //    ShowMsg(sendMsg.StartsWith("OK") ? 1 : 0, sendMsg);
+                //}
+
+                //if(currCount == 2)
+                //{
+                //    SubmitResponseMessage message = new SubmitResponseMessage
+                //    {
+                //        Name = "SubmitResponse",
+                //        Data = new SubmitResponseData
+                //        {
+                //            Serial = "BG7349116",
+                //            SubmitResult = "0",
+                //            ErrorMessage = ""
+                //        }
+                //    };
+                //    string jsonMessage = JsonConvert.SerializeObject(message, Formatting.None);
+
+                //    string sendMsg = _server.SendMessage(e.ClientId, jsonMessage);
+
+                //    ShowMsg(sendMsg.StartsWith("OK") ? 1 : 0, sendMsg);
+                //}
+                #endregion
+
+                currCount = currCount == 2 ? 0 : currCount;
+            }));
+        }
+        private void SocketServer_ReceivedMsg(object sender, ReceivedMsgEventArgs e)
         {
-            ShowMsg(0, "连接状态已变: " + status);
+            this.Invoke(new Action(() =>
+            {
+                if (e.Msg.StartsWith("OK"))
+                {
+                    ShowMsg(1, $"提示 [{e.Operation}]: {e.Msg}");
+                }
+                else if (e.Msg.StartsWith("NG"))
+                {
+                    ShowMsg(2, $"提示 [{e.Operation}]: {e.Msg}");
+                }
+            }));
         }
 
         private void ShowMsg(int type, string msg)
@@ -130,6 +174,7 @@ namespace UAS_MES_NEW.Make
             msg = msg.Replace("\r", "").Replace("\n", "");
             string msgTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
             string showMsg = $"{msgTime}: {msg}\n";
+
             if (type == 0)
             {
                 OperatResult.AppendText(showMsg, Color.Red);
@@ -138,6 +183,12 @@ namespace UAS_MES_NEW.Make
             {
                 OperatResult.AppendText(showMsg, Color.Green);
             }
+            else if (type == 2)
+            {
+                OperatResult.AppendText(showMsg, Color.YellowGreen);
+            }
+            OperatResult.SelectionStart = OperatResult.Text.Length;
+            OperatResult.ScrollToCaret();
         }
 
         private void UpdateSN(string type, string sn)
@@ -169,287 +220,424 @@ namespace UAS_MES_NEW.Make
             }
         }
 
-        public class SocketHandle
+        //private void btnSend_Click(object sender, EventArgs e)
+        //{
+        //    if (string.IsNullOrEmpty(txtMessage.Text))
+        //    {
+        //        ShowMsg(0, "请输入要发送的消息");
+        //        return;
+        //    }
+
+        //    var clientIds = _server.GetAllClientIds();
+        //    foreach (var clientId in clientIds)
+        //    {
+        //        string error = _server.SendMessage(clientId, txtMessage.Text);
+        //        if (!string.IsNullOrEmpty(error))
+        //        {
+        //            ShowMsg(0, $"发送到 {clientId} 失败: {error}");
+        //        }
+        //        else
+        //        {
+        //            ShowMsg(1, $"消息已发送到 {clientId}");
+        //        }
+        //    }
+        //}
+
+        public class VerifyResultData
         {
-            private Socket clientSocket;
-            private string serverIP;
-            private int serverPort;
-            private bool isConnected = false;
+            [JsonProperty("ErrorCode")]
+            public string ErrorCode { get; set; } = "0";
 
-            public event Action<string, string> OnFileReceived;
-            public event Action<string> OnMessageReceived;
-            public event Action<string> OnConnectionStatusChanged;
+            [JsonProperty("ErrorMsg")]
+            public string ErrorMsg { get; set; } = "";
 
-            public SocketHandle(string ip, int port)
+            [JsonProperty("Serial")]
+            public string Serial { get; set; }
+        }
+
+        public class VerifyResultMessage
+        {
+            [JsonProperty("Name")]
+            public string Name { get; set; } = "VerifyResult";
+
+            [JsonProperty("Data")]
+            public VerifyResultData Data { get; set; }
+        }
+
+
+        public class SubmitResponseData
+        {
+            [JsonProperty("Serial")]
+            public string Serial { get; set; }
+
+            [JsonProperty("SubmitResult")]
+            public string SubmitResult { get; set; } = "0";
+
+            [JsonProperty("ErrorMessage")]
+            public string ErrorMessage { get; set; } = "";
+        }
+
+        public class SubmitResponseMessage
+        {
+            [JsonProperty("Name")]
+            public string Name { get; set; } = "SubmitResponse";
+
+            [JsonProperty("Data")]
+            public SubmitResponseData Data { get; set; }
+        }
+
+
+        public class ReceivedDatasEventArgs : EventArgs
+        {
+            public string Message { get; set; }
+            public Socket ClientSocket { get; set; }
+            public string ClientId { get; set; }
+        }
+
+        public class ReceivedMsgEventArgs : EventArgs
+        {
+            public string Msg { get; set; }
+            public Exception Exception { get; set; }
+            public string Operation { get; set; }
+        }
+
+
+        public class SocketServer
+        {
+            private Socket _serverSocket;
+            private bool _isRunning = false;
+            private readonly Dictionary<string, Socket> _clients = new Dictionary<string, Socket>();
+
+            private class StateObject
             {
-                serverIP = ip;
-                serverPort = port;
-                clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+                public Socket ClientSocket { get; set; }
+                public string ClientId { get; set; }
+                public byte[] Buffer { get; set; }
+                public List<byte> DataBuffer { get; set; } = new List<byte>();
             }
 
-            public async Task<string> ConnectAsync()
+            public event EventHandler<ReceivedDatasEventArgs> ReceivedDatas;
+
+            public event EventHandler<ReceivedMsgEventArgs> ReceivedMsg;
+
+            public string Start(IPAddress _ipAddress, int _port, int _maxConnections)
             {
                 try
                 {
-                    IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(serverIP), serverPort);
-                    await Task.Factory.FromAsync(
-                        clientSocket.BeginConnect,
-                        clientSocket.EndConnect,
-                        endPoint,
-                        null);
-                    isConnected = true;
-                    if (OnConnectionStatusChanged != null)
+                    if (_isRunning)
                     {
-                        OnConnectionStatusChanged("连接成功");
+                        return "OK,服务器已经在运行中";
                     }
-                    StartListeningAsync();
 
-                    return "OK,连接成功";
+                    _serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+                    IPEndPoint localEndPoint = new IPEndPoint(_ipAddress, _port);
+                    _serverSocket.Bind(localEndPoint);
+                    _serverSocket.Listen(_maxConnections);
+                    _isRunning = true;
+
+                    _serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), _serverSocket);
+
+                    return "OK,服务器开始监听";
                 }
                 catch (Exception ex)
                 {
-                    return $"NG,连接失败: {ex.Message}";
+                    return $"NG,启动服务器失败: {ex.Message}";
                 }
             }
 
-            private async void StartListeningAsync()
+            public string Stop()
             {
-                while (isConnected)
+                try
                 {
-                    try
+                    if (!_isRunning)
                     {
-                        byte[] lengthBytes = new byte[4];
-                        int receivedLength = await ReceiveDataAsync(lengthBytes, 0, lengthBytes.Length);
+                        return "OK,服务器未运行";
+                    }
 
-                        if (receivedLength == 0) // 连接已断开
+                    _isRunning = false;
+
+                    List<string> clientIds;
+                    lock (_clients)
+                    {
+                        clientIds = new List<string>(_clients.Keys);
+                        foreach (var clientId in clientIds)
                         {
-                            isConnected = false;
-                            if (OnConnectionStatusChanged != null)
+                            try
                             {
-                                OnConnectionStatusChanged("连接已断开");
+                                if (_clients.TryGetValue(clientId, out var clientSocket))
+                                {
+                                    if (clientSocket != null && clientSocket.Connected)
+                                    {
+                                        clientSocket.Shutdown(SocketShutdown.Both);
+                                        clientSocket.Close();
+                                    }
+                                }
+                            }
+                            catch(Exception ex) 
+                            {
+                                return $"NG,停止服务器异常: {ex.Message}";
                             }
-                            break;
                         }
-
-                        int messageLength = BitConverter.ToInt32(lengthBytes, 0);
-
-                        // 接收消息内容
-                        byte[] messageBytes = new byte[messageLength];
-                        await ReceiveDataAsync(messageBytes, 0, messageLength);
-                        string message = Encoding.UTF8.GetString(messageBytes);
-
-                        // 根据消息类型触发不同事件
-                        ProcessMessage(message);
+                        _clients.Clear();
                     }
-                    catch (Exception ex)
+
+                    if (_serverSocket != null)
                     {
-                        isConnected = false;
-                        break;
+                        _serverSocket.Close();
+                        _serverSocket.Dispose();
+                        _serverSocket = null;
                     }
+
+                    return "OK,关闭服务器成功";
+                }
+                catch (Exception ex)
+                {
+                    return $"NG,停止服务器失败: {ex.Message}";
                 }
             }
-            private void ProcessMessage(string message)
+
+            private void AcceptCallback(IAsyncResult ar)
             {
-                if (message.StartsWith("[FILE_TRANSFER]"))
+                if (!_isRunning) return;
+
+                try
                 {
-                    if (OnMessageReceived != null)
+                    Socket serverSocket = (Socket)ar.AsyncState;
+                    Socket clientSocket = serverSocket.EndAccept(ar);
+
+                    string clientId = GenerateClientId(clientSocket);
+
+                    lock (_clients)
                     {
-                        OnMessageReceived("服务器准备发送文件: " + message.Substring(15));
+                        _clients[clientId] = clientSocket;
                     }
+
+                    OnReceivedMsg($"OK,客户端连接成功: {clientId}", "AcceptCallback", null);
+
+                    StateObject state = new StateObject
+                    {
+                        ClientSocket = clientSocket,
+                        ClientId = clientId,
+                        Buffer = new byte[8192]
+                    };
+
+                    clientSocket.BeginReceive(state.Buffer, 0, state.Buffer.Length,SocketFlags.None, new AsyncCallback(ReceiveCallback), state);
+
+                    serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), serverSocket);
                 }
-                else
+                catch (ObjectDisposedException)
                 {
-                    if (OnMessageReceived != null)
-                    {
-                        OnMessageReceived(message);
-                    }
+                    return; // 服务器已关闭,正常退出
+                }
+                catch (Exception ex)
+                {
+                    OnReceivedMsg("NG,接受客户端连接失败", "AcceptCallback", ex);
                 }
             }
 
-            public async Task<string> SendFileAsync(string filePath)
+            private void ReceiveCallback(IAsyncResult ar)
             {
-                if (!isConnected)
+                StateObject state = null;
+                int bytesRead = 0;
+
+                try
                 {
-                    return "NG,未连接到服务器";
-                }
+                    state = (StateObject)ar.AsyncState;
+                    bytesRead = state.ClientSocket.EndReceive(ar);
+
+                    if (bytesRead > 0)
+                    {
+                        for (int i = 0; i < bytesRead; i++)
+                        {
+                            state.DataBuffer.Add(state.Buffer[i]);
+                        }
+
+                        ProcessReceivedData(state, bytesRead);
 
-                if (!File.Exists(filePath))
+                        Array.Clear(state.Buffer, 0, state.Buffer.Length);
+                        state.ClientSocket.BeginReceive(state.Buffer, 0, state.Buffer.Length,SocketFlags.None, new AsyncCallback(ReceiveCallback), state);
+                    }
+                    else
+                    {
+                        OnReceivedMsg($"客户端 {state.ClientId} 断开连接", "ReceiveCallback", null);
+                        RemoveClient(state.ClientId, "客户端主动断开连接");
+                    }
+                }
+                catch (SocketException sockEx)
                 {
-                    return "NG,文件不存在: " + filePath;
+                    string clientId = state?.ClientId ?? "未知客户端";
+                    OnReceivedMsg($"NG,接收数据时Socket异常: {sockEx.Message}", "ReceiveCallback", sockEx);
+                    RemoveClient(clientId, $"Socket异常: {sockEx.SocketErrorCode}");
                 }
+                catch (Exception ex)
+                {
+                    string clientId = state?.ClientId ?? "未知客户端";
+                    OnReceivedMsg("NG,接收数据失败", "ReceiveCallback", ex);
+                    RemoveClient(clientId, $"接收数据错误: {ex.Message}");
+                }
+            }
 
+            private void ProcessReceivedData(StateObject state, int bytesRead)
+            {
                 try
                 {
-                    FileInfo fileInfo = new FileInfo(filePath);
-                    string fileName = fileInfo.Name;
-                    long fileSize = fileInfo.Length;
+                    for (int i = 0; i < bytesRead; i++)
+                    {
+                        state.DataBuffer.Add(state.Buffer[i]);
+                    }
 
-                    // 发送文件头信息 (文件名长度 + 文件名 + 文件大小)
-                    byte[] fileNameBytes = Encoding.UTF8.GetBytes(fileName);
-                    byte[] fileNameLengthBytes = BitConverter.GetBytes(fileNameBytes.Length);
-                    byte[] fileSizeBytes = BitConverter.GetBytes(fileSize);
+                    if (state.DataBuffer.Count >= 2)
+                    {
+                        byte[] allBytes = state.DataBuffer.ToArray();
+                        string jsonMessage = Encoding.Unicode.GetString(allBytes);
 
-                    // 组合发送数据
-                    byte[] header = new byte[fileNameLengthBytes.Length + fileNameBytes.Length + fileSizeBytes.Length];
-                    Array.Copy(fileNameLengthBytes, 0, header, 0, fileNameLengthBytes.Length);
-                    Array.Copy(fileNameBytes, 0, header, fileNameLengthBytes.Length, fileNameBytes.Length);
-                    Array.Copy(fileSizeBytes, 0, header, fileNameLengthBytes.Length + fileNameBytes.Length, fileSizeBytes.Length);
+                        jsonMessage = jsonMessage.Replace("\0", "").Trim();
 
-                    await SendDataAsync(header);
+                        if (jsonMessage.Contains("{") && jsonMessage.Contains("}"))
+                        {
+                            int firstBrace = jsonMessage.IndexOf('{');
+                            int lastBrace = jsonMessage.LastIndexOf('}');
+                            string validJson = jsonMessage.Substring(firstBrace, lastBrace - firstBrace + 1);
 
-                    // 发送文件内容
-                    using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
-                    {
-                        byte[] buffer = new byte[4096];
-                        int bytesRead;
-                        while ((bytesRead = await fileStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
+                            state.DataBuffer.Clear();
+                            OnReceivedDatas(state.ClientSocket, state.ClientId, validJson);
+                        }
+                        else
                         {
-                            await SendDataAsync(buffer, 0, bytesRead);
+                            OnReceivedMsg($"NG,不是有效JSON格式: {jsonMessage}", "ProcessReceivedData", null);
                         }
                     }
 
-                    return "OK,发送文件成功";
+                    Array.Clear(state.Buffer, 0, state.Buffer.Length);
                 }
                 catch (Exception ex)
                 {
-                    return "NG,发送文件失败: " + ex.Message;
+                    OnReceivedMsg($"NG,解码处理异常: {ex.Message}", "ProcessReceivedData", null);
                 }
             }
 
-            public async Task<string> ReceiveFileAsync(string savePath)
-            {
-                if (!isConnected)
-                {
-                    return "NG,未连接到服务器";
-                }
 
+            public string SendMessage(string clientId, string jsonMessage)
+            {
                 try
                 {
-                    // 接收文件头信息
-                    byte[] fileNameLengthBytes = new byte[4];
-                    await ReceiveDataAsync(fileNameLengthBytes, 0, fileNameLengthBytes.Length);
-                    int fileNameLength = BitConverter.ToInt32(fileNameLengthBytes, 0);
-
-                    byte[] fileNameBytes = new byte[fileNameLength];
-                    await ReceiveDataAsync(fileNameBytes, 0, fileNameLength);
-                    string fileName = Encoding.UTF8.GetString(fileNameBytes);
-
-                    //byte[] fileSizeBytes = new byte[8];
-                    byte[] fileSizeBytes = new byte[4];
-                    await ReceiveDataAsync(fileSizeBytes, 0, fileSizeBytes.Length);
-                    long fileSize = BitConverter.ToInt64(fileSizeBytes, 0);
-
-                    // 确保保存目录存在
-                    string directory = Path.GetDirectoryName(savePath);
-                    if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
+                    if (!_isRunning)
                     {
-                        Directory.CreateDirectory(directory);
+                        return "NG,服务器未运行";
                     }
 
-                    // 接收文件内容
-                    using (FileStream fileStream = new FileStream(savePath, FileMode.Create, FileAccess.Write))
+                    Socket clientSocket = null;
+                    lock (_clients)
                     {
-                        byte[] buffer = new byte[4096];
-                        long totalReceived = 0;
-
-                        while (totalReceived < fileSize)
+                        if (!_clients.TryGetValue(clientId, out clientSocket) || clientSocket == null)
                         {
-                            int toRead = (int)Math.Min(buffer.Length, fileSize - totalReceived);
-                            int received = await ReceiveDataAsync(buffer, 0, toRead);
-                            if (received <= 0)
-                            {
-                                break;
-                            }
-                            await fileStream.WriteAsync(buffer, 0, received);
-                            totalReceived += received;
+                            return $"NG,客户端 {clientId} 不存在或已断开";
                         }
                     }
 
-                    if (OnFileReceived != null)
+                    if (!clientSocket.Connected)
                     {
-                        OnFileReceived(fileName, savePath);
+                        RemoveClient(clientId, "连接已断开");
+                        return $"NG,客户端 {clientId} 连接已断开";
                     }
-                    return "OK,接收文件成功";
+
+                    byte[] messageBytes = Encoding.Unicode.GetBytes(jsonMessage);
+                    clientSocket.BeginSend(messageBytes, 0, messageBytes.Length, SocketFlags.None, new AsyncCallback(SendCallback),
+                        new { ClientId = clientId, ClientSocket = clientSocket });
+
+                    return $"OK,发送成功,已发送 字符数: {jsonMessage.Length}, 字节数: {messageBytes.Length} 到 {clientId}";
                 }
                 catch (Exception ex)
                 {
-                    return "NG,接收文件失败: " + ex.Message;
+                    return $"NG,发送失败: {ex.Message}";
                 }
             }
 
-            public async Task<string> SendMessageAsync(string message)
+            private void SendCallback(IAsyncResult ar)
             {
-                if (!isConnected)
-                {
-                    return "NG,未连接到服务器";
-                }
                 try
                 {
-                    byte[] messageBytes = Encoding.UTF8.GetBytes(message);
-                    byte[] lengthBytes = BitConverter.GetBytes(messageBytes.Length);
+                    dynamic state = ar.AsyncState;
+                    Socket clientSocket = state.ClientSocket;
+                    string clientId = state.ClientId;
 
-                    await SendDataAsync(lengthBytes);
-                    await SendDataAsync(messageBytes);
-                    return "OK,发送消息成功";
+                    int bytesSent = clientSocket.EndSend(ar);
+                    OnReceivedMsg($"OK,发送完成, 客户端: {clientId}, 字节数: {bytesSent}", "SendCallback", null);
                 }
                 catch (Exception ex)
                 {
-                    return "NG,发送消息失败: " + ex.Message;
+                    OnReceivedMsg("NG,发送回调失败", "SendCallback", ex);
                 }
             }
 
-            public async Task<string> ReceiveMessageAsync()
+            private void RemoveClient(string clientId, string reason)
             {
                 try
                 {
-                    // 先接收消息长度
-                    byte[] lengthBytes = new byte[4];
-                    await ReceiveDataAsync(lengthBytes, 0, lengthBytes.Length);
-                    int messageLength = BitConverter.ToInt32(lengthBytes, 0);
+                    Socket clientSocket = null;
+                    lock (_clients)
+                    {
+                        if (_clients.TryGetValue(clientId, out clientSocket))
+                        {
+                            _clients.Remove(clientId);
+                        }
+                    }
 
-                    // 接收消息内容
-                    byte[] messageBytes = new byte[messageLength];
-                    await ReceiveDataAsync(messageBytes, 0, messageLength);
+                    if (clientSocket != null)
+                    {
+                        try
+                        {
+                            if (clientSocket.Connected)
+                            {
+                                clientSocket.Shutdown(SocketShutdown.Both);
+                            }
+                            clientSocket.Close();
+                        }
+                        catch { }
+                    }
 
-                    return "OK," + Encoding.UTF8.GetString(messageBytes);
+                    OnReceivedMsg($"OK,移除客户端: {clientId}, 原因: {reason}", "RemoveClient", null);
                 }
                 catch (Exception ex)
                 {
-                    Console.WriteLine("接收消息失败: " + ex.Message);
-                    return null;
+                    OnReceivedMsg($"NG,移除客户端 {clientId} 失败", "RemoveClient", ex);
                 }
             }
 
-            private async Task SendDataAsync(byte[] data)
-            {
-                await SendDataAsync(data, 0, data.Length);
-            }
+            
 
-            private async Task SendDataAsync(byte[] data, int offset, int size)
+            private string GenerateClientId(Socket clientSocket)
             {
-                await Task.Factory.FromAsync((callback, state) => 
-                    clientSocket.BeginSend(data, offset, size, SocketFlags.None, callback, state),
-                    clientSocket.EndSend,
-                    null);
+                try
+                {
+                    if (clientSocket.RemoteEndPoint is IPEndPoint remoteEndPoint)
+                    {
+                        return $"{remoteEndPoint.Address}:{remoteEndPoint.Port}";
+                    }
+                }
+                catch { }
+                return $"Client_{DateTime.Now:yyyyMMddHHmmssfff}_{Guid.NewGuid().ToString().Substring(0, 6)}";
             }
 
-            private async Task<int> ReceiveDataAsync(byte[] data, int offset, int size)
+            protected virtual void OnReceivedDatas(Socket clientSocket, string clientId, string message)
             {
-                return await Task.Factory.FromAsync((callback, state) => 
-                    clientSocket.BeginReceive(data, offset, size, SocketFlags.None, callback, state),
-                    clientSocket.EndReceive,
-                    null);
+                ReceivedDatas?.Invoke(this, new ReceivedDatasEventArgs
+                {
+                    ClientSocket = clientSocket,
+                    ClientId = clientId,
+                    Message = message
+                });
             }
 
-            public void Close()
+            protected virtual void OnReceivedMsg(string Message, string operation, Exception exception)
             {
-                isConnected = false;
-                if (clientSocket != null && clientSocket.Connected)
+                ReceivedMsg?.Invoke(this, new ReceivedMsgEventArgs
                 {
-                    clientSocket.Shutdown(SocketShutdown.Both);
-                    clientSocket.Close();
-                }
+                    Msg = Message,
+                    Operation = operation,
+                    Exception = exception
+                });
             }
         }
     }
-}
+}

+ 47 - 0
UAS_MES_HYSX/FunctionCode/Make/Make_SocketClient.Designer.cs

@@ -0,0 +1,47 @@
+namespace UAS_MES_NEW.FunctionCode.Make
+{
+    partial class Make_SocketClient
+    {
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows Form Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.SuspendLayout();
+            // 
+            // Make_SocketClient
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 18F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.ClientSize = new System.Drawing.Size(800, 450);
+            this.Name = "Make_SocketClient";
+            this.Text = "Make_SocketClient";
+            this.Load += new System.EventHandler(this.Make_SocketClient_Load);
+            this.ResumeLayout(false);
+
+        }
+
+        #endregion
+    }
+}

+ 374 - 0
UAS_MES_HYSX/FunctionCode/Make/Make_SocketClient.cs

@@ -0,0 +1,374 @@
+using HslCommunication;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace UAS_MES_NEW.FunctionCode.Make
+{
+    public partial class Make_SocketClient : Form
+    {
+        public Make_SocketClient()
+        {
+            InitializeComponent();
+        }
+
+        string saveFile, sendFile;
+
+        SocketHandle client;
+
+        private async void Make_SocketClient_Load(object sender, EventArgs e)
+        {
+            string currentPath = Directory.GetParent(AppDomain.CurrentDomain.BaseDirectory).FullName;
+            saveFile = Path.Combine(currentPath, $"Received.txt");
+            sendFile = Path.Combine(currentPath, $"Send.txt");
+
+            client = new SocketHandle("127.0.0.1", 9979);
+            client.OnFileReceived += OnFileReceived;
+            client.OnMessageReceived += OnMessageReceived;
+            client.OnConnectionStatusChanged += OnConnectionStatusChanged;
+
+            string msg = await client.ConnectAsync();
+            if (!msg.StartsWith("OK"))
+            {
+                ShowMsg(0, msg);
+            }
+            ShowMsg(1, msg);
+
+            msg = await client.ReceiveFileAsync(saveFile);
+            if (!msg.StartsWith("OK"))
+            {
+                ShowMsg(0, msg);
+            }
+            ShowMsg(1, msg);
+        }
+
+        private async void OnFileReceived(string fileName, string savePath)
+        {
+            ShowMsg(1, "文件接收完成: " + fileName + " 保存到: " + savePath);
+            string msg = await client.SendFileAsync(sendFile);
+            if (msg.StartsWith("NG"))
+            {
+                ShowMsg(0, msg);
+            }
+            ShowMsg(1, "文件发送成功");
+        }
+
+        private void OnMessageReceived(string message)
+        {
+            ShowMsg(1, "收到服务器消息: " + message);
+        }
+
+        private void OnConnectionStatusChanged(string status)
+        {
+            ShowMsg(0, "连接状态已变: " + status);
+        }
+
+
+        private void ShowMsg(int type, string msg)
+        {
+            msg = msg.Replace("\r", "").Replace("\n", "");
+            string msgTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
+            string showMsg = $"{msgTime}: {msg}\n";
+            if (type == 0)
+            {
+                //OperatResult.AppendText(showMsg, Color.Red);
+            }
+            else if (type == 1)
+            {
+                //OperatResult.AppendText(showMsg, Color.Green);
+            }
+        }
+
+        public class SocketHandle
+        {
+            private Socket clientSocket;
+            private string serverIP;
+            private int serverPort;
+            private bool isConnected = false;
+
+            public event Action<string, string> OnFileReceived;
+            public event Action<string> OnMessageReceived;
+            public event Action<string> OnConnectionStatusChanged;
+
+            public SocketHandle(string ip, int port)
+            {
+                serverIP = ip;
+                serverPort = port;
+                clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+            }
+
+            public async Task<string> ConnectAsync()
+            {
+                try
+                {
+                    IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(serverIP), serverPort);
+                    await Task.Factory.FromAsync(
+                        clientSocket.BeginConnect,
+                        clientSocket.EndConnect,
+                        endPoint,
+                        null);
+                    isConnected = true;
+                    if (OnConnectionStatusChanged != null)
+                    {
+                        OnConnectionStatusChanged("连接成功");
+                    }
+                    StartListeningAsync();
+
+                    return "OK,连接成功";
+                }
+                catch (Exception ex)
+                {
+                    return $"NG,连接失败: {ex.Message}";
+                }
+            }
+
+            private async void StartListeningAsync()
+            {
+                while (isConnected)
+                {
+                    try
+                    {
+                        byte[] lengthBytes = new byte[4];
+                        int receivedLength = await ReceiveDataAsync(lengthBytes, 0, lengthBytes.Length);
+
+                        if (receivedLength == 0) // 连接已断开
+                        {
+                            isConnected = false;
+                            if (OnConnectionStatusChanged != null)
+                            {
+                                OnConnectionStatusChanged("连接已断开");
+                            }
+                            break;
+                        }
+
+                        int messageLength = BitConverter.ToInt32(lengthBytes, 0);
+
+                        // 接收消息内容
+                        byte[] messageBytes = new byte[messageLength];
+                        await ReceiveDataAsync(messageBytes, 0, messageLength);
+                        string message = Encoding.UTF8.GetString(messageBytes);
+
+                        // 根据消息类型触发不同事件
+                        ProcessMessage(message);
+                    }
+                    catch (Exception ex)
+                    {
+                        isConnected = false;
+                        break;
+                    }
+                }
+            }
+            private void ProcessMessage(string message)
+            {
+                if (message.StartsWith("[FILE_TRANSFER]"))
+                {
+                    if (OnMessageReceived != null)
+                    {
+                        OnMessageReceived("服务器准备发送文件: " + message.Substring(15));
+                    }
+                }
+                else
+                {
+                    if (OnMessageReceived != null)
+                    {
+                        OnMessageReceived(message);
+                    }
+                }
+            }
+
+            public async Task<string> SendFileAsync(string filePath)
+            {
+                if (!isConnected)
+                {
+                    return "NG,未连接到服务器";
+                }
+
+                if (!File.Exists(filePath))
+                {
+                    return "NG,文件不存在: " + filePath;
+                }
+
+                try
+                {
+                    FileInfo fileInfo = new FileInfo(filePath);
+                    string fileName = fileInfo.Name;
+                    long fileSize = fileInfo.Length;
+
+                    // 发送文件头信息 (文件名长度 + 文件名 + 文件大小)
+                    byte[] fileNameBytes = Encoding.UTF8.GetBytes(fileName);
+                    byte[] fileNameLengthBytes = BitConverter.GetBytes(fileNameBytes.Length);
+                    byte[] fileSizeBytes = BitConverter.GetBytes(fileSize);
+
+                    // 组合发送数据
+                    byte[] header = new byte[fileNameLengthBytes.Length + fileNameBytes.Length + fileSizeBytes.Length];
+                    Array.Copy(fileNameLengthBytes, 0, header, 0, fileNameLengthBytes.Length);
+                    Array.Copy(fileNameBytes, 0, header, fileNameLengthBytes.Length, fileNameBytes.Length);
+                    Array.Copy(fileSizeBytes, 0, header, fileNameLengthBytes.Length + fileNameBytes.Length, fileSizeBytes.Length);
+
+                    await SendDataAsync(header);
+
+                    // 发送文件内容
+                    using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
+                    {
+                        byte[] buffer = new byte[4096];
+                        int bytesRead;
+                        while ((bytesRead = await fileStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
+                        {
+                            await SendDataAsync(buffer, 0, bytesRead);
+                        }
+                    }
+
+                    return "OK,发送文件成功";
+                }
+                catch (Exception ex)
+                {
+                    return "NG,发送文件失败: " + ex.Message;
+                }
+            }
+
+            public async Task<string> ReceiveFileAsync(string savePath)
+            {
+                if (!isConnected)
+                {
+                    return "NG,未连接到服务器";
+                }
+
+                try
+                {
+                    // 接收文件头信息
+                    byte[] fileNameLengthBytes = new byte[4];
+                    await ReceiveDataAsync(fileNameLengthBytes, 0, fileNameLengthBytes.Length);
+                    int fileNameLength = BitConverter.ToInt32(fileNameLengthBytes, 0);
+
+                    byte[] fileNameBytes = new byte[fileNameLength];
+                    await ReceiveDataAsync(fileNameBytes, 0, fileNameLength);
+                    string fileName = Encoding.UTF8.GetString(fileNameBytes);
+
+                    //byte[] fileSizeBytes = new byte[8];
+                    byte[] fileSizeBytes = new byte[4];
+                    await ReceiveDataAsync(fileSizeBytes, 0, fileSizeBytes.Length);
+                    long fileSize = BitConverter.ToInt64(fileSizeBytes, 0);
+
+                    // 确保保存目录存在
+                    string directory = Path.GetDirectoryName(savePath);
+                    if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
+                    {
+                        Directory.CreateDirectory(directory);
+                    }
+
+                    // 接收文件内容
+                    using (FileStream fileStream = new FileStream(savePath, FileMode.Create, FileAccess.Write))
+                    {
+                        byte[] buffer = new byte[4096];
+                        long totalReceived = 0;
+
+                        while (totalReceived < fileSize)
+                        {
+                            int toRead = (int)Math.Min(buffer.Length, fileSize - totalReceived);
+                            int received = await ReceiveDataAsync(buffer, 0, toRead);
+                            if (received <= 0)
+                            {
+                                break;
+                            }
+                            await fileStream.WriteAsync(buffer, 0, received);
+                            totalReceived += received;
+                        }
+                    }
+
+                    if (OnFileReceived != null)
+                    {
+                        OnFileReceived(fileName, savePath);
+                    }
+                    return "OK,接收文件成功";
+                }
+                catch (Exception ex)
+                {
+                    return "NG,接收文件失败: " + ex.Message;
+                }
+            }
+
+            public async Task<string> SendMessageAsync(string message)
+            {
+                if (!isConnected)
+                {
+                    return "NG,未连接到服务器";
+                }
+                try
+                {
+                    byte[] messageBytes = Encoding.UTF8.GetBytes(message);
+                    byte[] lengthBytes = BitConverter.GetBytes(messageBytes.Length);
+
+                    await SendDataAsync(lengthBytes);
+                    await SendDataAsync(messageBytes);
+                    return "OK,发送消息成功";
+                }
+                catch (Exception ex)
+                {
+                    return "NG,发送消息失败: " + ex.Message;
+                }
+            }
+
+            public async Task<string> ReceiveMessageAsync()
+            {
+                try
+                {
+                    // 先接收消息长度
+                    byte[] lengthBytes = new byte[4];
+                    await ReceiveDataAsync(lengthBytes, 0, lengthBytes.Length);
+                    int messageLength = BitConverter.ToInt32(lengthBytes, 0);
+
+                    // 接收消息内容
+                    byte[] messageBytes = new byte[messageLength];
+                    await ReceiveDataAsync(messageBytes, 0, messageLength);
+
+                    return "OK," + Encoding.UTF8.GetString(messageBytes);
+                }
+                catch (Exception ex)
+                {
+                    Console.WriteLine("接收消息失败: " + ex.Message);
+                    return null;
+                }
+            }
+
+            private async Task SendDataAsync(byte[] data)
+            {
+                await SendDataAsync(data, 0, data.Length);
+            }
+
+            private async Task SendDataAsync(byte[] data, int offset, int size)
+            {
+                await Task.Factory.FromAsync((callback, state) =>
+                    clientSocket.BeginSend(data, offset, size, SocketFlags.None, callback, state),
+                    clientSocket.EndSend,
+                    null);
+            }
+
+            private async Task<int> ReceiveDataAsync(byte[] data, int offset, int size)
+            {
+                return await Task.Factory.FromAsync((callback, state) =>
+                    clientSocket.BeginReceive(data, offset, size, SocketFlags.None, callback, state),
+                    clientSocket.EndReceive,
+                    null);
+            }
+
+            public void Close()
+            {
+                isConnected = false;
+                if (clientSocket != null && clientSocket.Connected)
+                {
+                    clientSocket.Shutdown(SocketShutdown.Both);
+                    clientSocket.Close();
+                }
+            }
+        }
+    }
+}

+ 120 - 0
UAS_MES_HYSX/FunctionCode/Make/Make_SocketClient.resx

@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>

+ 9 - 0
UAS_MES_HYSX/UAS_MES_HYSX.csproj

@@ -737,6 +737,12 @@
     <Compile Include="FunctionCode\Make\Make_SmtTestCollection.Designer.cs">
       <DependentUpon>Make_SmtTestCollection.cs</DependentUpon>
     </Compile>
+    <Compile Include="FunctionCode\Make\Make_SocketClient.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="FunctionCode\Make\Make_SocketClient.Designer.cs">
+      <DependentUpon>Make_SocketClient.cs</DependentUpon>
+    </Compile>
     <Compile Include="FunctionCode\Make\Make_StencilPrint.cs">
       <SubType>Form</SubType>
     </Compile>
@@ -1770,6 +1776,9 @@
     <EmbeddedResource Include="FunctionCode\Make\Make_SmtTestCollection.resx">
       <DependentUpon>Make_SmtTestCollection.cs</DependentUpon>
     </EmbeddedResource>
+    <EmbeddedResource Include="FunctionCode\Make\Make_SocketClient.resx">
+      <DependentUpon>Make_SocketClient.cs</DependentUpon>
+    </EmbeddedResource>
     <EmbeddedResource Include="FunctionCode\Make\Make_StencilPrint.resx">
       <DependentUpon>Make_StencilPrint.cs</DependentUpon>
     </EmbeddedResource>