using AJR.Foundation.Helpers;
using AJR.General.Models.Communicator.ICommunicates;
using System.Net;
using System.Net.Sockets;
namespace AJR.General.Models.Communicator;
internal class TcpCommunicator : INetworkCommunicator, IDisposable
{
private TcpClient? _tcpClient;
private NetworkStream? _networkStream;
private readonly SemaphoreSlim _sendSemaphore = new SemaphoreSlim(1, 1);
public IPEndPoint? LocalEndPoint => _tcpClient?.Client.LocalEndPoint as IPEndPoint;
public IPEndPoint? RemoteEndPoint => _tcpClient?.Client.RemoteEndPoint as IPEndPoint;
public bool IsConnected => _tcpClient?.Connected == true;
public event Action<byte[]>? OnDataReceive;
public event Action? OnConnectionLost;
public bool Connect(IPEndPoint remoteEndPoint)
{
try
{
_tcpClient = new TcpClient
{
ReceiveTimeout = 5000, // 设置接收超时为5秒
SendTimeout = 1000 // 设置发送超时为1秒
};
_tcpClient.Connect(remoteEndPoint);
_networkStream = _tcpClient.GetStream();
return true;
}
catch
{
return false;
}
}
public bool Connect(IPAddress remoteIp, int port)
{
return Connect(new IPEndPoint(remoteIp, port));
}
public bool DisConnect()
{
try
{
_networkStream?.Close();
_tcpClient?.Close();
return true;
}
catch
{
return false;
}
}
public void Dispose()
{
DisConnect();
_sendSemaphore.Dispose();
}
public byte[] Send(byte[]? content)
{
return SendAsync(content).Result;
}
MemoryStream _memory = new();
byte[] buffer = new byte[1024];
int bytesRead;
public async Task<byte[]> SendAsync(byte[]? content)
{
if (_networkStream == null || content == null)
return Array.Empty<byte>();
await _sendSemaphore.WaitAsync();
try
{
_memory.SetLength(0);
await _networkStream.WriteAsync(content, 0, content.Length);
do
{
bytesRead = await _networkStream.ReadAsync(buffer, 0, buffer.Length);
_memory.Write(buffer, 0, bytesRead);
} while (_networkStream.DataAvailable);
return _memory.ToArray();
}
catch (Exception ex)
{
Log4Helper.Communication.Error($"TcpCommunicator SendReadAsync 报错", ex);
return Array.Empty<byte>();
}
finally
{
bytesRead = 0;
_sendSemaphore.Release();
}
}
}