根据我的理解,这些界限:
var client = await listener.AcceptTcpClientAsync();
var client = listener.AcceptTcpClient();
应该以相同的方式工作,但如果我尝试打开,例如,5k连接(不关闭它们),很快监听器(异步)会停止响应或抛出异常。
任何人都知道可能出错了什么?
示例类:
class ListenerTest
{
static int connectionNumber = 0;
static int port = 23456;
public void StartListening(bool async)
{
var listener = new TcpListener(IPAddress.Any, port);
listener.Start();
if (async)
{
var task = HandleConnectionsAsync(listener);
task.Wait();
}
else
HandleConnections(listener);
}
async Task HandleConnectionsAsync(TcpListener listener)
{
while (true)
{
Console.Write("Waiting for async connection...");
var client = await listener.AcceptTcpClientAsync();
Console.WriteLine("OK #" + connectionNumber);
connectionNumber++;
}
}
void HandleConnections(TcpListener listener)
{
while (true)
{
Console.Write("Waiting for sync connection...");
var client = listener.AcceptTcpClient();
Console.WriteLine("OK #" + connectionNumber);
connectionNumber++;
}
}
public static void ConnectTest(int count)
{
var ep = new IPEndPoint(IPAddress.Loopback, port);
for (var i = 0; i < count; i++)
new TcpClient().Connect(ep);
}
}
用法:
static void Main(string[] args)
{
var isAsync = true;
ThreadPool.QueueUserWorkItem(new WaitCallback(StartListening), isAsync);
ListenerTest.ConnectTest(5000);
}
static void StartListening(object state)
{
var my = new ListenerTest();
my.StartListening((bool)state);
}
答案 0 :(得分:4)
您的测试连接被GC杀死,如果您“固定”连接直到测试结束 - 您将获得5000个连接(我只是复制/粘贴并修复/测试您的代码)。重写连接测试:
public static void ConnectTest(int count)
{
var ep = new IPEndPoint(IPAddress.Loopback, port);
List<TcpClient> clients = new List<TcpClient>();
for (var i = 0; i < count; i++)
{
TcpClient cl = new TcpClient();
clients.Add(cl);
cl.Connect(ep);
}
}
另请注意,在“真实世界”条件下,您需要在启动侦听器循环之前添加类似的内容:
ThreadPool.SetMinThreads(100, 100);
这使您的代码在“突发”连接计数/网络加载下工作。我们刚刚在linux / mono下成功“加载测试”了7,5K连接。
答案 1 :(得分:1)
您无法与单台计算机建立100,000个连接。 TCP / IP只有16 bits for a port number (maximum 64k ports),并且有很多这些用于(或保留)用于操作系统或各种服务。
通常,only 16,383 of these ports are available用于传入客户端连接,您需要与all the other processes that use TCP/IP regularly共享它们。