gpt4 book ai didi

c# - 在 .NET 中查找下一个 TCP 端口的线程安全方式(通过多个进程)

转载 作者:太空狗 更新时间:2023-10-30 01:28:42 25 4
gpt4 key购买 nike

请注意,您可以在此处找到类似的问题:Find the next TCP port in .NET

我的问题是这个问题的解决方案(接受的答案)不是线程安全的:Find the next TCP port in .NET - Top answer

static int FreeTcpPort()
{
TcpListener l = new TcpListener(IPAddress.Loopback, 0);
l.Start();
int port = ((IPEndPoint)l.LocalEndpoint).Port;
l.Stop();
return port;
}

我写了一个测试证明:

private readonly BlockingCollection<int> _freePorts = new BlockingCollection<int>();

[Test]
public void FreeTcpPort_ShouldBeThreadSafe()
{
// Act
Parallel.For(0, 10000,
index =>
{
int freeTcpPort = FreeTcpPort();
_freePorts.Add(freeTcpPort);
Console.WriteLine(freeTcpPort);
} );

var query = _freePorts.GroupBy(x => x)
.Where(g => g.Count() > 1)
.Select(y => new { Element = y.Key, Counter = y.Count() })
.ToList();

// Assert
Assert.That(query.All(x => x.Counter == 1), () => query.First(x => x.Counter > 1).ToString());
}

上面的测试是不稳定的。在我的机器上,它失败的次数超过 50%。这是失败测试的控制台输出的一部分:

51470
51472
51473
51365
51475
51367
51366
51474
51475
51476
51478
51479
51480

问题是在这种情况下端口 51475 被返回了两次。请注意,同一端口是从 2 个并行运行的线程返回的,而不是因为它在端口范围内循环并重叠(发生在较高的循环计数时)。

请注意,仅仅为我的用例添加一个锁定语句是不够的,因为我将此动态端口用于并行运行的系统测试,这些测试在单独的进程中运行。因此,我正在寻找一种解决方案,它总是为并行运行的进程返回一个唯一且免费的 TCP 端口。

我如何构建一个实用程序来从并行运行的进程中获取空闲的 TCP 端口,而不会遇到竞争条件?

最佳答案

How can I build a utility to get a free TCP port from parallel running processes, without running into race conditions?

你不能。使用一些临时“空闲”端口的想法从一开始就是错误的,因为在具有多个进程的系统上,实际上空闲的东西可能会从一个时刻变为另一个时刻 - 无论您的应用程序本身是否使用线程。因此,即使您找到了一些现在空闲的端口,它也可能在您设法绑定(bind)到它之前已被另一个进程使用。

正确的方法是不要找到空闲端口然后绑定(bind)到它。正确的方法是将您的监听器绑定(bind)到端口 0,然后确定实际使用了哪个端口。然后直接使用这个已经创建的监听器套接字,而不是关闭它并尝试使用它用于某些新套接字的端口。

关于c# - 在 .NET 中查找下一个 TCP 端口的线程安全方式(通过多个进程),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58063770/

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