|
|
@@ -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
|
|
|
+ });
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-}
|
|
|
+}
|