I'm trying to make client get some data from server using TCP. But it works only once. Then stream.DataAvailable is always false.
Client code:
while (!StopEvent.WaitOne(WaitTime, true))
{
try
{
if (TcpClient == null || !TcpClient.Connected)
{
if (TcpClient != null)
{
TcpClient.Close();
TcpClient = null;
}
TcpClient = new TcpClient(MasterHost, MasterMonitoringPort) {NoDelay = true};
}
var stream = TcpClient.GetStream();
stream.WriteTimeout = TimeoutMs;
stream.ReadTimeout = TimeoutMs;
stream.Write(GetMasterStateRequestBytes, 0, GetMasterStateRequestBytes.Length);
var serialisedDataBuilder = new StringBuilder();
if (stream.DataAvailable)
{
while (stream.DataAvailable)
{
var bytesRead = stream.Read(BytesBuffer, 0, BytesBuffer.Length);
serialisedDataBuilder.Append(Encoding.UTF8.GetString(BytesBuffer, 0, bytesRead));
}
var responses = MonitoringResponse.StringToResponses(serialisedDataBuilder.ToString());
foreach (var response in responses)
{
if (response.MonitoringResponseType == MonitoringResponseType.ProvideMasterStateInfo && response.Parameters is MasterStateInfo masterStateInfo)
MasterStateInfo = masterStateInfo;
}
}
}
catch (Exception exception)
{
LastException = exception;
TcpClient?.Close();
TcpClient = null;
}
Thread.Sleep(10*1000);
}
Server code :
while (!StopEvent.WaitOne(WaitTime, true))
{
try
{
if (TcpListener == null)
{
Application.Tracer.Trace(this, TracerEventKind.Info, "Starting TcpListener");
TcpListener = new TcpListener(IPAddress.Any, MasterNetworkServer.MonitoringPort);
TcpListener.Start();
}
if (TcpListener.Pending())
{
Application.Tracer.Trace(this, TracerEventKind.Info, "TcpListener is pending, start processing");
var client = TcpListener.AcceptTcpClient();
var stream = client.GetStream();
stream.WriteTimeout = TimeoutMs;
stream.ReadTimeout = TimeoutMs;
var serialisedDataBuilder = new StringBuilder();
if (stream.DataAvailable)
{
do
{
var bytesRead = stream.Read(BytesBuffer, 0, BytesBuffer.Length);
serialisedDataBuilder.Append(Encoding.UTF8.GetString(BytesBuffer, 0, bytesRead));
} while (stream.DataAvailable);
Application.Tracer.Trace(this, TracerEventKind.Info, "Bytes received");
var requests =
MonitoringRequest.StringToRequests(serialisedDataBuilder.ToString(), distinct: true);
var responses = new List<MonitoringResponse>();
if (requests.Any())
{
Application.Tracer.Trace(this, TracerEventKind.Info,
$"Start to processing {requests.Count} requests");
foreach (var request in requests)
{
responses.Add(HandleMonitoringRequest(request));
Application.Tracer.Trace(this, TracerEventKind.Info, "Response made");
}
Application.Tracer.Trace(this, TracerEventKind.Info, "All responses made");
}
var responsesBytes = MonitoringResponse.ResponsesToBytes(responses);
stream.Write(responsesBytes, 0, responsesBytes.Length);
}
}
}
catch(Exception exception)
{
Application.Tracer.Trace(this, TracerEventKind.Info, $"Monitoring network service exception: {exception.Message}");
}
Thread.Sleep(0);
Avoiding stupid restrictions text. Avoiding stupid restrictions text. Avoiding stupid restrictions text. Avoiding stupid restrictions text. Avoiding stupid restrictions text. Avoiding stupid restrictions text.
The way to fix it was to close stream and client (with method .Close()
) after each session and also add some sleep before checking isDataAvailable