gpt4 book ai didi

c# - 解释 NetCore 上 C# TcpClient/TcpListener 的奇怪行为

转载 作者:行者123 更新时间:2023-11-30 17:36:05 24 4
gpt4 key购买 nike

我在 Windows 10 上运行 NetCore,我有两个程序 - 我在本地运行的服务器和客户端。

执行顺序如下:

  • 运行服务器 - 有一个处理客户端的循环
  • 运行客户端 - 客户端完成它的工作并且进程终止
  • 第二次运行客户端

此序列使用以下代码从服务器生成以下输出:

Waiting for client.
Reading message.
Incoming message: This message is longer than what
Sending message.
Closing connection.
Waiting for client.
Reading message.
Incoming message: This message is longer than what
Sending message.
Closing connection.
Waiting for client.

以及来自客户端的以下输出:

Connecting to server.
Sending message.
Reading message.
Incoming message: Thank you!


Connecting to server.
Sending message.
Reading message.

Unhandled Exception: System.AggregateException: One or more errors occurred. (Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.) ---> System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host

换句话说 - 第二次尝试运行客户端以异常结束。那是奇怪的部分。

这是我用于重现问题的最小代码示例。

服务器代码:

public static async Task StartServerAsync()
{
TcpListener listener = new TcpListener(IPAddress.Any, 1234);
listener.Server.NoDelay = true;
listener.Server.LingerState = new LingerOption(true, 0);
listener.Start();

while (true)
{
Console.WriteLine("Waiting for client.");
using (TcpClient client = await listener.AcceptTcpClientAsync())
{
client.NoDelay = true;
client.LingerState = new LingerOption(true, 0);

Console.WriteLine("Reading message.");
using (NetworkStream stream = client.GetStream())
{
byte[] buffer = new byte[32];
int len = await stream.ReadAsync(buffer, 0, buffer.Length);
string incomingMessage = Encoding.UTF8.GetString(buffer, 0, len);
Console.WriteLine("Incoming message: {0}", incomingMessage);


Console.WriteLine("Sending message.");
byte[] message = Encoding.UTF8.GetBytes("Thank you!");
await stream.WriteAsync(message, 0, message.Length);
Console.WriteLine("Closing connection.");
}
}
}
}

客户端代码:

public static async Task StartClientAsync()
{
using (TcpClient client = new TcpClient())
{
client.NoDelay = true;
client.LingerState = new LingerOption(true, 0);

Console.WriteLine("Connecting to server.");
await client.ConnectAsync("127.0.0.1", 1234);

Console.WriteLine("Sending message.");
using (NetworkStream stream = client.GetStream())
{
byte[] buffer = Encoding.UTF8.GetBytes("This message is longer than what the server is willing to read.");
await stream.WriteAsync(buffer, 0, buffer.Length);

Console.WriteLine("Reading message.");
int len = await stream.ReadAsync(buffer, 0, buffer.Length);
string message = Encoding.UTF8.GetString(buffer, 0, len);

Console.WriteLine("Incoming message: {0}", message);
}
}
}

奇怪的是,如果我们将客户端的消息从

"This message is longer than what the server is willing to read."

"This message is short."

客户端的两个实例在没有崩溃的情况下完成并产生相同的输出。

请注意,如果我省略了设置 LingerState 的所有三行,则没有任何区别。如果我将 LingerState 设置为

,行为也没有区别

新的 LingerState(true, 5)

如果我将 NoDelay 设置为 false,也没有区别。换句话说,在任一侧为 LingerState 和 NoDelay 设置任何值似乎对崩溃没有任何影响。防止崩溃的唯一方法是在服务器端读取来自客户端的整个输入。

这很奇怪,我想知道是否有人可以解释一下。我不确定它是否也适用于 .NET Framework,仅在 NetCore 1.0.0 和 Windows 10 上进行了测试。

最佳答案

.NET Core 团队终于在 GitHub 上回答了这个问题。

长答案 - 请参阅 https://github.com/dotnet/corefx/issues/13114 的最后评论

简答 -

The behavior is expected, and is by-design.

关于c# - 解释 NetCore 上 C# TcpClient/TcpListener 的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40258230/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com