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();
}
}
}