C#套接字服务器无法承载超过800个客户端

5
我有一个C# socket服务器。最多能连接的客户端数量约为800个。如果客户端超过800个,新的客户端会收到套接字错误WSAECONNREFUSED 10061。 如何提高最大客户端连接数?
套接字写入在socket.BeginXXX和socket.EndXXX之间进行。目标:框架4.0。协议:IP4,TCP。

2
听取队列已满。你能贴一些代码吗? - Darren
路由器或防火墙也可以限制可用端口的范围。 - vgru
@Groo 这里只有一个端口在运作,即服务器正在侦听的端口。 - user207421
3个回答

4
监听器的后备队列已满。当后备队列已满时,Windows会开始向进一步的传入连接发送RST,这些连接在客户端处变为“连接被拒绝”。您可以像其他答案中所述那样提高后备队列长度,但它真正意味着的是您没有足够快地处理接受请求。仔细检查执行此操作的代码,并优化其路径。确保它不会执行任何其他操作,如阻塞I/O、磁盘I/O或其他网络操作。一旦连接被接受,它就会从后备队列中移除,因此其他传入连接可以成功。

2

当将服务器套接字设置为监听状态时,可以设置backlog。这是等待被接受的最大连接数。

其他所有问题可能都是硬件问题 - 尝试在不同的机器上运行程序。

以下是一个示例:

Socket serversocket = ...
serversocket.Listen(1000);

硬件问题怎么会导致TCP重置和拒绝连接? - user207421
我在考虑网络卡的方面。这只是一个假设,可能完全不相关。 - Johannes

2

嗨,我找到了我的问题的答案。我创建了一个额外的线程来接受连接。例如:

原来的代码:

IPEndPoint myEndpoint = new IPEndPoint(IPAddress.Parse(_serverAddress), _port);
 _serverSocket = new Socket(myEndpoint.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

 _serverSocket.Bind(myEndpoint);
 _serverSocket.Listen((int)SocketOptionName.MaxConnections);

_serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), _serverSocket);

.....


private void AcceptCallback(IAsyncResult result)
        {
            ConnectionInfo connection = new ConnectionInfo();
            try
            {
                Socket s = (Socket)result.AsyncState;
                connection.Socket = s.EndAccept(result);

                connection.Buffer = new byte[1024];
                connection.Socket.BeginReceive(connection.Buffer,
                    0, connection.Buffer.Length, SocketFlags.None,
                    new AsyncCallback(ReceiveCallback),
                    connection);
            }
            catch (SocketException exc)
            {
                CloseConnection(connection, "Exception in Accept");
            }
            catch (Exception exc)
            {
                CloseConnection(connection, "Exception in Accept");
            }
            finally
            {

                    _serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), result.AsyncState);
            }
        }

通过这种方式,客户端连接数不会超过800。

目前我写的是:

 IPEndPoint myEndpoint = new IPEndPoint(IPAddress.Parse(_serverAddress), _port);
 _serverSocket = new Socket(myEndpoint.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

 _serverSocket.Bind(myEndpoint);
 _serverSocket.Listen((int)SocketOptionName.MaxConnections);

acceptThread = new Thread(new ThreadStart(ExecuteAccept));
acceptThread.Start();

......

private void ExecuteAccept()
        {

            while (true)
            {

                ConnectionInfo connection = new ConnectionInfo();
                try
                {
                    connection.Socket = _serverSocket.Accept();

                    connection.Buffer = new byte[1024];
                    connection.Socket.BeginReceive(connection.Buffer, 0, connection.Buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), connection);
                }
                catch (SocketException exc)
                {
                    CloseConnection(connection, "Exception in Accept");
                }
                catch (Exception exc)
                {
                    CloseConnection(connection, "Exception in Accept");
                }
            }
        }

通过这种方式,客户端连接数超过了2000。我使用BeginXXX和EndXXX进行读写操作。


我很困惑,有人能给我更多的信息吗?如果我有一个循环创建1000个连接到监听器上...为什么我会得到“Additional information:No connection could be made because the target machine actively refused it”这个错误,当有一个像MaxConnectoins = 2147483647这样的backlog时……我该如何编写代码来监视监听器上的情况...... 即如何知道监听器何时会拒绝连接......假设这就是它所做的。错误代码10061,请帮忙谢谢 - Seabizkit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接