Я использую проект WinForm для подключения к TcpClient
, который каждые 5 секунд отправляет мне сообщение.
Для этого я создал Thread
, который выполняет while(some condition)
и читает данные черезNetworkStream
и если есть данные, некоторые пользовательские EventHandler
и в графическом интерфейсе я получаю данные с таймером, который тикает каждую 1 секунду
При чтении все работает хорошо, и явозможность данных без проблем.Но после Я почему-то переписываюсь на удаленный сервер, получая бесконечное количество данных, возвращающихся мне с очень высокой скоростью, и мне кажется, что данные, которые я получаю, повреждены.
мой класс клиента
public class mTcpClient
{
public mTcpClient()
{
StringEncoder = System.Text.Encoding.UTF8;
ReadLoopIntervalMs = 10;
}
private Thread _rxThread = null;
public System.Text.Encoding StringEncoder { get; set; }
private TcpClient _client = null;
private NetworkStream _networkStream = null;
public event EventHandler<Message> DataReceived;
internal bool QueueStop { get; set; }
internal int ReadLoopIntervalMs { get; set; }
public bool AutoTrimStrings { get; set; }
public mTcpClient Connect(string hostNameOrIpAddress, int port)
{
if (string.IsNullOrEmpty(hostNameOrIpAddress))
{
throw new ArgumentNullException("hostNameOrIpAddress");
}
_client = new TcpClient();
_client.Connect(hostNameOrIpAddress, port);
_networkStream = _client.GetStream();
StartRxThread();
return this;
}
private void StartRxThread()
{
if (_rxThread != null) { return; }
_rxThread = new Thread(ListenerLoop);
_rxThread.IsBackground = true;
_rxThread.Start();
}
public mTcpClient Disconnect()
{
if (_client == null) { return this; }
_client.Close();
_client = null;
_networkStream.Close();
_networkStream = null;
QueueStop = true;
return this;
}
public TcpClient TcpClient { get { return _client; } }
private void ListenerLoop(object state)
{
while (!QueueStop)
{
try
{
RunLoopStep();
}
catch
{
// TODO
}
Thread.Sleep(ReadLoopIntervalMs);
}
_rxThread = null;
}
private void RunLoopStep()
{
if (_client == null) { return; }
if (_client.Connected == false) { return; }
if (_client.Available == 0)
{
Thread.Sleep(ReadLoopIntervalMs);
return;
}
var bytesReceived = new List<byte>();
while (_client.Available > 0 && _client.Connected)
{
byte[] nextByte = new byte[1];
_networkStream.Read(nextByte, 0, nextByte.Length);
bytesReceived.AddRange(nextByte);
}
if (bytesReceived.Count > 0)
{
NotifyEndTransmissionRx(_client, bytesReceived.ToArray());
}
}
private void NotifyEndTransmissionRx(TcpClient client, byte[] msg)
{
if (DataReceived != null)
{
Message m = new Message(msg, client, StringEncoder);
DataReceived(this, m);
}
}
public void Write(string data)
{
if (data == null) { return; }
if (_client == null) { throw new Exception("Cannot send data to a null TcpClient (check to see if Connect was called)"); }
var encodedData = StringEncoder.GetBytes(data);
_networkStream.Write(encodedData, 0, encodedData.Length);
_networkStream.Flush();
}
}
мой класс сообщения
public class Message
{
private TcpClient _tcpClient;
private System.Text.Encoding _encoder = null;
internal Message(byte[] data, TcpClient tcpClient, System.Text.Encoding stringEncoder)
{
Data = data;
_tcpClient = tcpClient;
_encoder = stringEncoder;
}
public byte[] Data { get; private set; }
public string MessageString
{
get
{
return _encoder.GetString(Data);
}
}
public TcpClient TcpClient { get { return _tcpClient; } }
}
обычный поток данных без обратной записи
Нормальный поток данных после обратной записи ![](https://i.stack.imgur.com/mpVy6.png)