gpt4 book ai didi

c# - 在不阻塞的情况下建立和验证来自客户端的连接的最佳方法是什么?

转载 作者:行者123 更新时间:2023-12-04 17:07:29 25 4
gpt4 key购买 nike

我有一个 TcpListener server可以通过调用 server.AcceptTcpClientAsync() 打开与客户端的连接.不幸的是,有随机的、不需要的流量连接到我不关心的服务器,所以我添加了一个方法,Task<bool> Handshake(TcpClient client) , 以验证客户端应该能够与服务器对话。

获取连接的简单方法是:

async Task<TcpClient> GetClient(TcpListener server)
{
while (true)
{
var client = await server.AcceptTcpClientAsync();
if (await Handshake(client))
{
return client;
}
client.Dispose();
}
}

不幸的是,握手过程在等待虚假连接时会花费非零时间来超时,如果它花费的时间比下一个连接出现所需的时间长,挂起的连接将堆积起来并且永远不会得到服务。

我知道像 Task.WhenAny 这样的 API允许同时运行多个异步操作,但我似乎无法为这个连接过程找到合适的模型。

我想要的:

  1. 预计只有一次成功连接。
  2. 当连接到达时,尝试握手。如果握手成功,则将其返回并处理任何其他挂起的连接。如果不是,则处理连接。
  3. 正在进行的握手不应阻止循环接受新连接。
  4. 进行中的握手次数始终有可能为 0、1 或大于 1。

有什么好的方法可以用代码表达吗?

最佳答案

您可以使用Channel 进行安全的跨线程通信

var channel = Channel.CreateBounded<TcpClient>(100);
var writer = channel.Writer;
var reader = channel.Reader;

_ = GetClient(server);

var successClient = await Task.Run(async () =>
{
await foreach (var client in reader.ReadAllAsync())
{
if (await Handshake(client))
{
return client;
}
client.Dispose();
}
return null;
});

//mark the channel that no more data is going to be written to it
writer.TryComplete();

//run through the remaining clients in the channel and dispose of them
await foreach (var client in reader.ReadAllAsync())
{
client.Dispose();
}

//use successClient here


async Task<TcpClient> GetClient(TcpListener server)
{
while (true)
{
var client = await server.AcceptTcpClientAsync();
await writer.WriteAsync(client);
}
}

关于c# - 在不阻塞的情况下建立和验证来自客户端的连接的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70266579/

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