c# - TCP 客户端 - 服务器连接
问题描述
我试图让客户端使用 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 之前添加一些睡眠
推荐阅读
- youtube-api - YouTube 数据 API“youtube#channel”查询:“brandingSettings.image”自 2020 年 11 月 11 日起不再可用?
- c# - 如何在 sonarcloud.io 中为 c# 项目启用代码覆盖率
- python - 使用具有许多不同键的 R 巨大 json 进行解析
- virtualization - libvirt:virt-install 在安装时挂起
- database - 设计创意数据库并保持效率
- node.js - 猫鼬填充数组上的功能
- f# - 在 F# 中,如何对 Nullable 进行模式匹配
反对空? - ios - 静态快速操作在目标 c iOS 中不起作用
- java - 关于 getter/setter 方法的 Java 问题
- asp.net - Visual Studio 2019 添加区域缺失