Запрос:
напиши класс с функцией на C#, которые реализуют возможность отправлять массивы байт по указанному TCP адресу и порту. При вызове этой функции переданный массив байт помещается в очередь и отправляется после отправки предыдущего массива байт. Отправка происходит внутри потока, который может быть запущен при помощи вызова другой функции Start. Поток отправляющий массивы байт может быть остановлен вызовом функции Stop. В случае разрыва TCP соединения должна производиться попытка соединиться вновь спустя 1 секунду. Открытие TCP соединения производится при вызове Start.
Ответ:
using System;
using System.Collections.Concurrent;
using System.IO;
using System.Net.Sockets;
using System.Threading;
public class TcpByteSender
{
private readonly string _address;
private readonly int _port;
private TcpClient _client;
private NetworkStream _stream;
private Thread _sendThread;
private readonly ConcurrentQueue _queue;
private bool _isRunning;
public TcpByteSender(string address, int port)
{
_address = address;
_port = port;
_queue = new ConcurrentQueue();
}
public void Start()
{
_client = new TcpClient();
_client.Connect(_address, _port);
_stream = _client.GetStream();
_isRunning = true;
_sendThread = new Thread(SendLoop);
_sendThread.Start();
}
public void Stop()
{
_isRunning = false;
_sendThread.Join();
_stream.Close();
_client.Close();
}
public void Enqueue(byte[] data)
{
_queue.Enqueue(data);
}
private void SendLoop()
{
while (_isRunning)
{
if (_queue.TryDequeue(out byte[] data))
{
try
{
_stream.Write(data, 0, data.Length);
}
catch (IOException)
{
Reconnect();
}
}
else
{
Thread.Sleep(10); // Добавьте небольшую задержку, чтобы избежать активного ожидания
}
}
}
private void Reconnect()
{
_stream.Close();
_client.Close();
while (_isRunning)
{
try
{
_client = new TcpClient();
_client.Connect(_address, _port);
_stream = _client.GetStream();
break;
}
catch (SocketException)
{
Thread.Sleep(1000);
}
}
}
}