Make_SocketClient.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. using HslCommunication;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.ComponentModel;
  5. using System.Data;
  6. using System.Drawing;
  7. using System.IO;
  8. using System.Linq;
  9. using System.Net;
  10. using System.Net.Sockets;
  11. using System.Text;
  12. using System.Threading.Tasks;
  13. using System.Windows.Forms;
  14. namespace UAS_MES_NEW.FunctionCode.Make
  15. {
  16. public partial class Make_SocketClient : Form
  17. {
  18. public Make_SocketClient()
  19. {
  20. InitializeComponent();
  21. }
  22. string saveFile, sendFile;
  23. SocketHandle client;
  24. private async void Make_SocketClient_Load(object sender, EventArgs e)
  25. {
  26. string currentPath = Directory.GetParent(AppDomain.CurrentDomain.BaseDirectory).FullName;
  27. saveFile = Path.Combine(currentPath, $"Received.txt");
  28. sendFile = Path.Combine(currentPath, $"Send.txt");
  29. client = new SocketHandle("127.0.0.1", 9979);
  30. client.OnFileReceived += OnFileReceived;
  31. client.OnMessageReceived += OnMessageReceived;
  32. client.OnConnectionStatusChanged += OnConnectionStatusChanged;
  33. string msg = await client.ConnectAsync();
  34. if (!msg.StartsWith("OK"))
  35. {
  36. ShowMsg(0, msg);
  37. }
  38. ShowMsg(1, msg);
  39. msg = await client.ReceiveFileAsync(saveFile);
  40. if (!msg.StartsWith("OK"))
  41. {
  42. ShowMsg(0, msg);
  43. }
  44. ShowMsg(1, msg);
  45. }
  46. private async void OnFileReceived(string fileName, string savePath)
  47. {
  48. ShowMsg(1, "文件接收完成: " + fileName + " 保存到: " + savePath);
  49. string msg = await client.SendFileAsync(sendFile);
  50. if (msg.StartsWith("NG"))
  51. {
  52. ShowMsg(0, msg);
  53. }
  54. ShowMsg(1, "文件发送成功");
  55. }
  56. private void OnMessageReceived(string message)
  57. {
  58. ShowMsg(1, "收到服务器消息: " + message);
  59. }
  60. private void OnConnectionStatusChanged(string status)
  61. {
  62. ShowMsg(0, "连接状态已变: " + status);
  63. }
  64. private void ShowMsg(int type, string msg)
  65. {
  66. msg = msg.Replace("\r", "").Replace("\n", "");
  67. string msgTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
  68. string showMsg = $"{msgTime}: {msg}\n";
  69. if (type == 0)
  70. {
  71. //OperatResult.AppendText(showMsg, Color.Red);
  72. }
  73. else if (type == 1)
  74. {
  75. //OperatResult.AppendText(showMsg, Color.Green);
  76. }
  77. }
  78. public class SocketHandle
  79. {
  80. private Socket clientSocket;
  81. private string serverIP;
  82. private int serverPort;
  83. private bool isConnected = false;
  84. public event Action<string, string> OnFileReceived;
  85. public event Action<string> OnMessageReceived;
  86. public event Action<string> OnConnectionStatusChanged;
  87. public SocketHandle(string ip, int port)
  88. {
  89. serverIP = ip;
  90. serverPort = port;
  91. clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  92. }
  93. public async Task<string> ConnectAsync()
  94. {
  95. try
  96. {
  97. IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(serverIP), serverPort);
  98. await Task.Factory.FromAsync(
  99. clientSocket.BeginConnect,
  100. clientSocket.EndConnect,
  101. endPoint,
  102. null);
  103. isConnected = true;
  104. if (OnConnectionStatusChanged != null)
  105. {
  106. OnConnectionStatusChanged("连接成功");
  107. }
  108. StartListeningAsync();
  109. return "OK,连接成功";
  110. }
  111. catch (Exception ex)
  112. {
  113. return $"NG,连接失败: {ex.Message}";
  114. }
  115. }
  116. private async void StartListeningAsync()
  117. {
  118. while (isConnected)
  119. {
  120. try
  121. {
  122. byte[] lengthBytes = new byte[4];
  123. int receivedLength = await ReceiveDataAsync(lengthBytes, 0, lengthBytes.Length);
  124. if (receivedLength == 0) // 连接已断开
  125. {
  126. isConnected = false;
  127. if (OnConnectionStatusChanged != null)
  128. {
  129. OnConnectionStatusChanged("连接已断开");
  130. }
  131. break;
  132. }
  133. int messageLength = BitConverter.ToInt32(lengthBytes, 0);
  134. // 接收消息内容
  135. byte[] messageBytes = new byte[messageLength];
  136. await ReceiveDataAsync(messageBytes, 0, messageLength);
  137. string message = Encoding.UTF8.GetString(messageBytes);
  138. // 根据消息类型触发不同事件
  139. ProcessMessage(message);
  140. }
  141. catch (Exception ex)
  142. {
  143. isConnected = false;
  144. break;
  145. }
  146. }
  147. }
  148. private void ProcessMessage(string message)
  149. {
  150. if (message.StartsWith("[FILE_TRANSFER]"))
  151. {
  152. if (OnMessageReceived != null)
  153. {
  154. OnMessageReceived("服务器准备发送文件: " + message.Substring(15));
  155. }
  156. }
  157. else
  158. {
  159. if (OnMessageReceived != null)
  160. {
  161. OnMessageReceived(message);
  162. }
  163. }
  164. }
  165. public async Task<string> SendFileAsync(string filePath)
  166. {
  167. if (!isConnected)
  168. {
  169. return "NG,未连接到服务器";
  170. }
  171. if (!File.Exists(filePath))
  172. {
  173. return "NG,文件不存在: " + filePath;
  174. }
  175. try
  176. {
  177. FileInfo fileInfo = new FileInfo(filePath);
  178. string fileName = fileInfo.Name;
  179. long fileSize = fileInfo.Length;
  180. // 发送文件头信息 (文件名长度 + 文件名 + 文件大小)
  181. byte[] fileNameBytes = Encoding.UTF8.GetBytes(fileName);
  182. byte[] fileNameLengthBytes = BitConverter.GetBytes(fileNameBytes.Length);
  183. byte[] fileSizeBytes = BitConverter.GetBytes(fileSize);
  184. // 组合发送数据
  185. byte[] header = new byte[fileNameLengthBytes.Length + fileNameBytes.Length + fileSizeBytes.Length];
  186. Array.Copy(fileNameLengthBytes, 0, header, 0, fileNameLengthBytes.Length);
  187. Array.Copy(fileNameBytes, 0, header, fileNameLengthBytes.Length, fileNameBytes.Length);
  188. Array.Copy(fileSizeBytes, 0, header, fileNameLengthBytes.Length + fileNameBytes.Length, fileSizeBytes.Length);
  189. await SendDataAsync(header);
  190. // 发送文件内容
  191. using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
  192. {
  193. byte[] buffer = new byte[4096];
  194. int bytesRead;
  195. while ((bytesRead = await fileStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
  196. {
  197. await SendDataAsync(buffer, 0, bytesRead);
  198. }
  199. }
  200. return "OK,发送文件成功";
  201. }
  202. catch (Exception ex)
  203. {
  204. return "NG,发送文件失败: " + ex.Message;
  205. }
  206. }
  207. public async Task<string> ReceiveFileAsync(string savePath)
  208. {
  209. if (!isConnected)
  210. {
  211. return "NG,未连接到服务器";
  212. }
  213. try
  214. {
  215. // 接收文件头信息
  216. byte[] fileNameLengthBytes = new byte[4];
  217. await ReceiveDataAsync(fileNameLengthBytes, 0, fileNameLengthBytes.Length);
  218. int fileNameLength = BitConverter.ToInt32(fileNameLengthBytes, 0);
  219. byte[] fileNameBytes = new byte[fileNameLength];
  220. await ReceiveDataAsync(fileNameBytes, 0, fileNameLength);
  221. string fileName = Encoding.UTF8.GetString(fileNameBytes);
  222. //byte[] fileSizeBytes = new byte[8];
  223. byte[] fileSizeBytes = new byte[4];
  224. await ReceiveDataAsync(fileSizeBytes, 0, fileSizeBytes.Length);
  225. long fileSize = BitConverter.ToInt64(fileSizeBytes, 0);
  226. // 确保保存目录存在
  227. string directory = Path.GetDirectoryName(savePath);
  228. if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
  229. {
  230. Directory.CreateDirectory(directory);
  231. }
  232. // 接收文件内容
  233. using (FileStream fileStream = new FileStream(savePath, FileMode.Create, FileAccess.Write))
  234. {
  235. byte[] buffer = new byte[4096];
  236. long totalReceived = 0;
  237. while (totalReceived < fileSize)
  238. {
  239. int toRead = (int)Math.Min(buffer.Length, fileSize - totalReceived);
  240. int received = await ReceiveDataAsync(buffer, 0, toRead);
  241. if (received <= 0)
  242. {
  243. break;
  244. }
  245. await fileStream.WriteAsync(buffer, 0, received);
  246. totalReceived += received;
  247. }
  248. }
  249. if (OnFileReceived != null)
  250. {
  251. OnFileReceived(fileName, savePath);
  252. }
  253. return "OK,接收文件成功";
  254. }
  255. catch (Exception ex)
  256. {
  257. return "NG,接收文件失败: " + ex.Message;
  258. }
  259. }
  260. public async Task<string> SendMessageAsync(string message)
  261. {
  262. if (!isConnected)
  263. {
  264. return "NG,未连接到服务器";
  265. }
  266. try
  267. {
  268. byte[] messageBytes = Encoding.UTF8.GetBytes(message);
  269. byte[] lengthBytes = BitConverter.GetBytes(messageBytes.Length);
  270. await SendDataAsync(lengthBytes);
  271. await SendDataAsync(messageBytes);
  272. return "OK,发送消息成功";
  273. }
  274. catch (Exception ex)
  275. {
  276. return "NG,发送消息失败: " + ex.Message;
  277. }
  278. }
  279. public async Task<string> ReceiveMessageAsync()
  280. {
  281. try
  282. {
  283. // 先接收消息长度
  284. byte[] lengthBytes = new byte[4];
  285. await ReceiveDataAsync(lengthBytes, 0, lengthBytes.Length);
  286. int messageLength = BitConverter.ToInt32(lengthBytes, 0);
  287. // 接收消息内容
  288. byte[] messageBytes = new byte[messageLength];
  289. await ReceiveDataAsync(messageBytes, 0, messageLength);
  290. return "OK," + Encoding.UTF8.GetString(messageBytes);
  291. }
  292. catch (Exception ex)
  293. {
  294. Console.WriteLine("接收消息失败: " + ex.Message);
  295. return null;
  296. }
  297. }
  298. private async Task SendDataAsync(byte[] data)
  299. {
  300. await SendDataAsync(data, 0, data.Length);
  301. }
  302. private async Task SendDataAsync(byte[] data, int offset, int size)
  303. {
  304. await Task.Factory.FromAsync((callback, state) =>
  305. clientSocket.BeginSend(data, offset, size, SocketFlags.None, callback, state),
  306. clientSocket.EndSend,
  307. null);
  308. }
  309. private async Task<int> ReceiveDataAsync(byte[] data, int offset, int size)
  310. {
  311. return await Task.Factory.FromAsync((callback, state) =>
  312. clientSocket.BeginReceive(data, offset, size, SocketFlags.None, callback, state),
  313. clientSocket.EndReceive,
  314. null);
  315. }
  316. public void Close()
  317. {
  318. isConnected = false;
  319. if (clientSocket != null && clientSocket.Connected)
  320. {
  321. clientSocket.Shutdown(SocketShutdown.Both);
  322. clientSocket.Close();
  323. }
  324. }
  325. }
  326. }
  327. }