From d0ded5cd9bf5070a120bad58b5be21fe2ac6a4ff Mon Sep 17 00:00:00 2001
From: C3032 <C3032@BC3032>
Date: 星期六, 20 十二月 2025 16:41:09 +0800
Subject: [PATCH] test

---
 IDViewer_2D/TcpServerManager.cs |  272 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 272 insertions(+), 0 deletions(-)

diff --git a/IDViewer_2D/TcpServerManager.cs b/IDViewer_2D/TcpServerManager.cs
new file mode 100644
index 0000000..f7c6a7c
--- /dev/null
+++ b/IDViewer_2D/TcpServerManager.cs
@@ -0,0 +1,272 @@
+锘縰sing SmartScanner.ViewModel;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace SmartScanner
+{
+    public class TcpServerManager : IDisposable
+    {
+        private TcpListener _listener;
+        public static bool _isRunning;
+        private CancellationTokenSource _cts;
+        private Func<Task<int[]>> _imageProcessingHandler; // 鍥惧儚澶勭悊濮旀墭
+        private int _outputIOCount; // 杈撳嚭IO鏁伴噺
+        // 蹇冭烦閰嶇疆
+        public bool EnableHeartbeat { get; private set; }
+        public string HeartbeatCommand { get; private set; }
+        public int HeartbeatInterval { get; private set; }
+
+        // 瀹㈡埛绔垪琛ㄧ鐞嗭紙濡傛灉闇�瑕佽窡韪涓鎴风锛�
+        // private ConcurrentDictionary<string, TcpClient> _connectedClients = new ConcurrentDictionary<string, TcpClient>();
+
+        public event Action<string> LogMessage;
+        public event Action<string, string> CommandReceived;
+        public event Action<string> ClientConnected;
+        public event Action<string> ClientDisconnected;
+
+        public TcpServerManager(bool enableHeartbeat, string heartbeatCommand, int heartbeatInterval,
+                               Func<Task<int[]>> imageProcessingHandler, int outputIOCount)
+        {
+            EnableHeartbeat = enableHeartbeat;
+            HeartbeatCommand = heartbeatCommand ?? "heartBeat";
+            HeartbeatInterval = heartbeatInterval > 0 ? heartbeatInterval : 1000;
+            _imageProcessingHandler = imageProcessingHandler ?? throw new ArgumentNullException(nameof(imageProcessingHandler));
+            _outputIOCount = outputIOCount > 0 ? outputIOCount : 1;
+        }
+        /// <summary>
+        /// TCP鏈嶅姟鍣ㄥ紑濮嬩睛鍚�
+        /// </summary>
+        /// <param name="ip">鏈嶅姟鍣↖P鍦板潃</param>
+        /// <param name="port">鏈嶅姟鍣ㄧ鍙�</param>
+        public async Task StartAsync(string ip, int port)
+        {
+            if (port == -1) return;
+            _cts = new CancellationTokenSource();
+            _isRunning = true;
+            _listener = new TcpListener(IPAddress.Parse(ip), port);
+            _listener.Start();
+
+            LogMessage?.Invoke($"TCP鏈嶅姟鍣ㄥ凡鍚姩锛屽紑濮嬩睛鍚� {ip}:{port}");
+            LogMessage?.Invoke($"蹇冭烦妫�娴�: {(EnableHeartbeat ? "宸插惎鐢�" : "宸茬鐢�")}");
+            if (EnableHeartbeat)
+            {
+                LogMessage?.Invoke($"蹇冭烦鎸囦护: {HeartbeatCommand}, 闂撮殧: {HeartbeatInterval}ms");
+            }
+
+            try
+            {
+                while (_isRunning)
+                {
+                    var acceptTask = _listener.AcceptTcpClientAsync();
+                    var cancelTask = Task.Delay(-1, _cts.Token);
+
+                    var completedTask = await Task.WhenAny(acceptTask, cancelTask);
+
+                    if (completedTask == cancelTask || _cts.Token.IsCancellationRequested)
+                    {
+                        break;
+                    }
+                    var client = await acceptTask;
+                    _ = HandleClientAsync(client);
+                }
+            }
+            catch (Exception ex)
+            {
+                LogMessage?.Invoke($"鏈嶅姟鍣ㄩ敊璇�: {ex.Message}");
+            }
+        }
+
+        private async Task HandleClientAsync(TcpClient client)
+        {
+            var clientId = client.Client.RemoteEndPoint?.ToString() ?? "鏈煡瀹㈡埛绔�";
+            ClientConnected?.Invoke(clientId);
+            LogMessage?.Invoke($"瀹㈡埛绔凡杩炴帴: {clientId}");
+
+            try
+            {
+                using (client)
+                using (var stream = client.GetStream())
+                {
+                    // 浣跨敤NetworkStream璇诲彇
+                    byte[] buffer = new byte[4096];
+                    MemoryStream ms = new MemoryStream();
+
+                    while (!_cts.IsCancellationRequested && client.Connected)
+                    {
+                        // 妫�鏌ユ暟鎹槸鍚﹀彲鐢�
+                        if (!stream.DataAvailable)
+                        {
+                            await Task.Delay(10, _cts.Token); // 鐭殏绛夊緟
+                            continue;
+                        }
+
+                        // 鍚屾璇诲彇鏂瑰紡
+                        int bytesRead = stream.Read(buffer, 0, buffer.Length);
+                        if (bytesRead == 0) // 杩炴帴宸插叧闂�
+                        {
+                            LogMessage?.Invoke($"瀹㈡埛绔� {clientId} 姝e父鏂紑");
+                            break;
+                        }
+
+                        ms.Write(buffer, 0, bytesRead);
+
+                        // 澶勭悊瀹屾暣娑堟伅锛堟秷鎭互鎹㈣绗︾粨灏撅級
+                        string receivedData = Encoding.ASCII.GetString(ms.ToArray());
+                        //if (receivedData.Contains('\n'))
+                        //{
+                        string[] messages = receivedData.Split('\n');
+                        for (int i = 0; i < messages.Length - 1; i++) // 鏈�鍚庝竴娈靛彲鑳戒笉瀹屾暣
+                        {
+                            string message = messages[i].Trim();
+                            if (!string.IsNullOrEmpty(message))
+                            {
+                                await ProcessMessageAsync(message, stream, clientId);
+                            }
+                        }
+
+                        // 淇濈暀涓嶅畬鏁寸殑閮ㄥ垎
+                        ms.SetLength(0);
+                        if (!string.IsNullOrEmpty(messages.Last()))
+                        {
+                            ms.Write(Encoding.ASCII.GetBytes(messages.Last()), 0, messages.Last().Length);
+                        }
+                        //}
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                LogMessage?.Invoke($"澶勭悊瀹㈡埛绔� {clientId} 鏃跺嚭閿�: {ex.Message}");
+            }
+            finally
+            {
+                ClientDisconnected?.Invoke(clientId);
+                LogMessage?.Invoke($"瀹㈡埛绔柇寮�: {clientId}");
+            }
+        }
+
+        private async Task ProcessMessageAsync(string message, NetworkStream stream, string clientId)
+        {
+            LogMessage?.Invoke($"鏉ヨ嚜 {clientId}: {message}");
+
+            Console.WriteLine($"{DateTime.Now:HH:mm:ss:fff}锛氭娴嬪埌瑙﹀彂淇″彿{message}");
+            EnhancedLogViewModel.Instance.AddLog($"{DateTime.Now:HH:mm:ss:fff}锛氭娴嬪埌瑙﹀彂淇″彿{message}");
+            // 澶勭悊蹇冭烦
+            if (EnableHeartbeat && message == HeartbeatCommand)
+            {
+                byte[] ack = Encoding.ASCII.GetBytes($"{HeartbeatCommand}_ACK\n");
+                await stream.WriteAsync(ack, 0, ack.Length);
+                return;
+            }
+
+            // 澶勭悊涓氬姟娑堟伅
+            var parts = message.Split(',');
+            if (parts.Length >= 2 && int.TryParse(parts[0], out var functionCode))
+            {
+                // 澶勭悊瑙﹀彂淇″彿 (鏆傚畾鍔熻兘鐮佷负3锛屽緟鍚庣画涓庡鎴锋矡閫�)
+                if (functionCode == 3)
+                {
+                    await HandleTriggerCommand(stream, clientId);
+                }
+                else
+                {
+                    // 鍏朵粬鍔熻兘鐮佸鐞�
+                    var response = $"{functionCode},0,Invalid function code\n";
+                    byte[] responseBytes = Encoding.ASCII.GetBytes(response);
+                    await stream.WriteAsync(responseBytes, 0, responseBytes.Length);
+                }
+            }
+        }
+        private async Task HandleTriggerCommand(NetworkStream stream, string clientId)
+        {
+            try
+            {
+                LogMessage?.Invoke($"寮�濮嬪鐞嗚Е鍙戝懡浠わ紝杩涜鍥惧儚閲囬泦鍜屾帹鐞�...");
+                // 璋冪敤鍥惧儚澶勭悊濮旀墭
+                int[] processingResults = await _imageProcessingHandler()
+         .ConfigureAwait(false); // 閬垮厤姝婚攣
+                if (processingResults == null || processingResults.Length != _outputIOCount)
+                {
+                    throw new InvalidOperationException($"鍥惧儚澶勭悊缁撴灉鏃犳晥锛岄鏈焮_outputIOCount}涓緭鍑猴紝瀹為檯寰楀埌{processingResults?.Length ?? 0}");
+                }
+
+                // 鏋勫缓鍝嶅簲娑堟伅
+                var responseBuilder = new StringBuilder();
+                responseBuilder.Append("3,"); // 鍔熻兘鍙�
+                responseBuilder.Append(_outputIOCount); // 杈撳嚭IO鏁�
+
+                // 娣诲姞姣忎釜鐐逛綅鐨勫鐞嗙粨鏋�
+                foreach (var result in processingResults)
+                {
+                    responseBuilder.Append($",{result}");
+                }
+
+                responseBuilder.Append("\n"); // 缁撴潫绗�
+
+                string response = responseBuilder.ToString();
+                LogMessage?.Invoke($"杩斿洖缁撴灉: {response.Trim()}");
+                EnhancedLogViewModel.Instance.AddLog($"{DateTime.Now:HH:mm:ss:fff}锛氭娴嬪畬鎴愶紝杩斿洖缁撴灉{response.Trim()}");
+                // 鍙戦�佸搷搴�
+                byte[] responseBytes = Encoding.ASCII.GetBytes(response);
+                await stream.WriteAsync(responseBytes, 0, responseBytes.Length);
+            }
+            catch (Exception ex)
+            {
+                LogMessage?.Invoke($"澶勭悊瑙﹀彂鍛戒护鏃跺嚭閿�: {ex.Message}");
+
+                // 鍙戦�侀敊璇搷搴�
+                var errorResponse = $"3,0,Error: {ex.Message}\n";
+                byte[] errorBytes = Encoding.ASCII.GetBytes(errorResponse);
+                await stream.WriteAsync(errorBytes, 0, errorBytes.Length);
+            }
+        }
+
+        private async Task StartHeartbeatAsync(StreamWriter writer, CancellationToken token)
+        {
+            try
+            {
+                while (!token.IsCancellationRequested)
+                {
+                    await writer.WriteLineAsync(HeartbeatCommand);
+                    await Task.Delay(HeartbeatInterval, token);
+                }
+            }
+            catch (OperationCanceledException)
+            {
+                // 姝e父鍙栨秷
+            }
+            catch (Exception ex)
+            {
+                LogMessage?.Invoke($"蹇冭烦浠诲姟閿欒: {ex.Message}");
+            }
+        }
+
+        public void Stop()
+        {
+            _isRunning = false;
+            _cts?.Cancel();
+            try
+            {
+                _listener?.Stop();
+                LogMessage?.Invoke("TCP鏈嶅姟鍣ㄥ凡鍋滄");
+            }
+            catch (Exception ex)
+            {
+                LogMessage?.Invoke($"鍋滄鏈嶅姟鍣ㄦ椂鍑洪敊: {ex.Message}");
+            }
+        }
+
+        public void Dispose()
+        {
+            Stop();
+            _cts?.Dispose();
+        }
+    }
+}

--
Gitblit v1.9.3