TCP 客户端-服务器连接
TCP client - server connection
我正在尝试让客户端使用 TCP 从服务器获取一些数据。
但它只工作一次。那么 stream.DataAvailable 总是假的。
客户代码:
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);
}
服务器代码:
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);
避免愚蠢的限制文本。
避免愚蠢的限制文本。
避免愚蠢的限制文本。
避免愚蠢的限制文本。
避免愚蠢的限制文本。
避免愚蠢的限制文本。
修复它的方法是在每次会话后关闭流和客户端(使用方法 .Close()
),并在检查 isDataAvailable
之前添加一些睡眠
我正在尝试让客户端使用 TCP 从服务器获取一些数据。 但它只工作一次。那么 stream.DataAvailable 总是假的。
客户代码:
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);
}
服务器代码:
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);
避免愚蠢的限制文本。 避免愚蠢的限制文本。 避免愚蠢的限制文本。 避免愚蠢的限制文本。 避免愚蠢的限制文本。 避免愚蠢的限制文本。
修复它的方法是在每次会话后关闭流和客户端(使用方法 .Close()
),并在检查 isDataAvailable