using System; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; namespace ConnectionUtil { /// /// TCP客户端包装类 /// /// /// TCP客户端包装类 /// public class TcpClientWrapper : IDisposable { private System.Net.Sockets.TcpClient _client; private NetworkStream _stream; private readonly string _host; private readonly int _port; private bool _isConnected; private readonly CancellationTokenSource _cts; private Task _heartbeatTask; private readonly SemaphoreSlim _sendReceiveLock; /// /// 初始化TCP客户端 /// /// 服务器地址 /// 服务器端口 public TcpClientWrapper(string host = "127.0.0.1", int port = 6543) { _host = host; _port = port; _cts = new CancellationTokenSource(); _sendReceiveLock = new SemaphoreSlim(1, 1); } /// /// 异步连接到服务器 /// /// 连接是否成功 public async Task ConnectAsync() { try { _client = new System.Net.Sockets.TcpClient(); await _client.ConnectAsync(_host, _port); _stream = _client.GetStream(); _isConnected = true; // 启动心跳任务 _heartbeatTask = StartHeartbeatAsync(_cts.Token); Console.WriteLine($"成功连接到服务器 {_host}:{_port}"); return true; } catch (Exception ex) { Console.WriteLine($"连接服务器失败:{ex.Message}"); return false; } } /// /// 同步连接到服务器 /// /// 连接是否成功 public bool Connect() { try { _client = new System.Net.Sockets.TcpClient(); _client.Connect(_host, _port); _stream = _client.GetStream(); _isConnected = true; // 启动心跳任务 _heartbeatTask = StartHeartbeatAsync(_cts.Token); return true; } catch (Exception ex) { Console.WriteLine($"连接服务器失败:{ex.Message}"); return false; } } /// /// 启动心跳检测 /// private async Task StartHeartbeatAsync(CancellationToken token) { while (!token.IsCancellationRequested && _isConnected) { try { await Task.Delay(20000, token); // 20秒发送一次心跳 if (_isConnected) { await SendMessageAsync("ping"); } } catch (OperationCanceledException) { break; } catch (Exception) { _isConnected = false; break; } } } /// /// 发送消息并接收响应 /// /// 响应数据类型 /// 要发送的数据对象 /// 超时时间 /// 服务器响应数据 public async Task SendMessageAsync(string message, TimeSpan? timeout = null) { if (!_isConnected) { throw new InvalidOperationException("未连接到服务器"); } TimeSpan actualTimeout = timeout ?? TimeSpan.FromSeconds(30); if (!await _sendReceiveLock.WaitAsync(actualTimeout)) { throw new TimeoutException("等待发送超时"); } try { byte[] messageBytes = Encoding.UTF8.GetBytes(message + "\r\n"); // 发送消息 await _stream.WriteAsync(messageBytes, 0, messageBytes.Length); // 接收响应 byte[] buffer = new byte[1024]; StringBuilder response = new StringBuilder(); int bytesRead; CancellationTokenSource cts = new CancellationTokenSource(actualTimeout); try { // 读取直到遇到换行符 while ((bytesRead = await _stream.ReadAsync(buffer, 0, buffer.Length)) > 0) { string received = Encoding.UTF8.GetString(buffer, 0, bytesRead); response.Append(received); if (received.EndsWith("\r\n")) { break; } if (cts.Token.IsCancellationRequested) { throw new TimeoutException("接收响应超时"); } } } finally { cts.Dispose(); } string jsonResponse = response.ToString().TrimEnd('\r', '\n'); Console.WriteLine($"收到服务器响应:{jsonResponse}"); // 反序列化响应 return jsonResponse; } catch (Exception ex) { Console.WriteLine($"发送消息失败:{ex.Message}"); _isConnected = false; throw; } finally { _sendReceiveLock.Release(); } } /// /// 同步发送消息并接收响应 /// /// 响应数据类型 /// 要发送的数据对象 /// 超时时间 /// 服务器响应数据 public string SendMessage(string message, TimeSpan? timeout = null) { timeout = timeout ?? TimeSpan.FromSeconds(30); try { // 使用 Task.Run 来执行异步操作,并等待结果 return Task.Run(() => SendMessageAsync(message, timeout)).Result; } catch (AggregateException ae) { // 解包异常 throw ae.InnerException; } } /// /// 检查是否已连接 /// public bool IsConnected { get { return _isConnected; } } /// /// 释放资源 /// public void Dispose() { _cts.Cancel(); _isConnected = false; if (_stream != null) { _stream.Dispose(); } if (_client != null) { _client.Dispose(); } _cts.Dispose(); if (_sendReceiveLock != null) { _sendReceiveLock.Dispose(); } } /// /// 关闭连接 /// public void Close() { Dispose(); } } }