私はC#ソケットサーバーを持っています。サーバーに接続できる最大クライアント数は約 800 です。クライアントが 800 を超えると、新しいクライアントがソケット エラー WSAECONNREFUSED 10061 を受け取ります。
socket.BeginXXX と socket.EndXXX の間のソケット書き込み。ターゲット: フレームワーク 4.0。プロトコル: IP4、TCP
私はC#ソケットサーバーを持っています。サーバーに接続できる最大クライアント数は約 800 です。クライアントが 800 を超えると、新しいクライアントがソケット エラー WSAECONNREFUSED 10061 を受け取ります。
socket.BeginXXX と socket.EndXXX の間のソケット書き込み。ターゲット: フレームワーク 4.0。プロトコル: IP4、TCP
リスナーのバックログ キューがいっぱいです。バックログ キューがいっぱいになると、Windows は RST を後続の着信接続に送信し始めます。これは、関連するクライアントで「接続が拒否されました」になります。ここで他の回答に従ってバックログキューの長さを上げることができますが、それが実際に意味することは、受け入れを十分に速く処理していないということです。それを行うコードをよく見て、パスに油を注いでください。I/O、ディスク I/O、その他のネットワーク操作のブロックなど、他に何もしないことを確認してください。接続が受け入れられると、バックログ キューから取り除かれ、他の受信接続が成功できるようになります。
こんにちは、私の質問に対する答えを見つけました。接続を受け入れるための追加のスレッドを作成します。例えば:
前
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 で行います。
サーバーソケットをリッスン状態に設定すると、バックログを設定できます。これは、受け入れを待機できる接続の最大数です。
それ以外はすべてハードウェアの問題である可能性があります。別のマシンでプログラムを実行してみてください。
ここに例があります
Socket serversocket = ...
serversocket.Listen(1000);