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 OnFileReceived; public event Action OnMessageReceived; public event Action OnConnectionStatusChanged; public SocketHandle(string ip, int port) { serverIP = ip; serverPort = port; clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); } public async Task 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 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 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 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 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 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(); } } } } }