TcpCommunicator 一个TCP的收发类,支持长数据读写

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

 

posted @ 2025-03-06 18:19  cchong005  阅读(8)  评论(0)    收藏  举报