5

私はC#ソケットサーバーを持っています。サーバーに接続できる最大クライアント数は約 800 です。クライアントが 800 を超えると、新しいクライアントがソケット エラー WSAECONNREFUSED 10061 を受け取ります。

socket.BeginXXX と socket.EndXXX の間のソケット書き込み。ターゲット: フレームワーク 4.0。プロトコル: IP4、TCP

4

3 に答える 3

4

リスナーのバックログ キューがいっぱいです。バックログ キューがいっぱいになると、Windows は RST を後続の着信接続に送信し始めます。これは、関連するクライアントで「接続が拒否されました」になります。ここで他の回答に従ってバックログキューの長さを上げることができますが、それが実際に意味することは、受け入れを十分に速く処理していないということです。それを行うコードをよく見て、パスに油を注いでください。I/O、ディスク I/O、その他のネットワーク操作のブロックなど、に何もしないことを確認してください。接続が受け入れられると、バックログ キューから取り除かれ、他の受信接続が成功できるようになります。

于 2012-06-13T11:26:31.180 に答える
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 で行います。

于 2012-06-15T05:07:23.337 に答える
2

サーバーソケットをリッスン状態に設定すると、バックログを設定できます。これは、受け入れを待機できる接続の最大数です。

それ以外はすべてハードウェアの問題である可能性があります。別のマシンでプログラムを実行してみてください。

ここに例があります

Socket serversocket = ...
serversocket.Listen(1000);
于 2012-06-13T11:00:13.237 に答える