发送时无法立即完成非阻塞套接字操作

Nik*_*hil 5 c# sockets

我正在为游戏编写服务器,并且希望能够处理数千个并发用户。出于这个原因,我使用了非阻塞套接字并使用了 poll 方法。但是,我确实创建了多个线程来处理数据库和 Web 调用,其中一些线程会向用户发送响应。在这些线程之一中,在发送时,我收到错误“无法立即完成非阻塞套接字操作”。什么可能导致这个问题?我想这是因为在调用 send 的同时进行了轮询。如果我使用beginAsync,是否需要停止这个错误?我想锁定套接字,但我不希望我的主线程因此被阻塞。

Kir*_*ril 5

我不知道您使用的是哪种非阻塞轮询套接字调用,但我建议您使用Async 套接字调用(而不是 Begin)。有关Async 调用与 Begin之间区别的更多信息,请参阅:BeginConnect 和 ConnectAsync 之间有什么区别?

异步调用会自动在操作系统级别进行“轮询”,这比您的轮询效率高得多。事实上,它们使用 IO 完成端口,这可能是您可以在 Windows 上用来处理大量客户端连接/请求的最快和最有效的东西。

至于错误,我认为这是非阻塞套接字的正常操作,所以你只需要优雅地处理它。

更新

您的服务器可能应该执行以下操作:

// Process the accept for the socket listener.
private void ProcessAccept(SocketAsyncEventArgs e)
{
    Socket s = e.AcceptSocket;
    if (s.Connected)
    {
        try
        {
            SocketAsyncEventArgs readEventArgs = this.readWritePool.Pop();
            if (readEventArgs != null)
            {
                // Get the socket for the accepted client connection and put it into the 
                // ReadEventArg object user token.
                readEventArgs.UserToken = new Token(s, this.bufferSize);

                Interlocked.Increment(ref this.numConnectedSockets);
                Console.WriteLine("Client connection accepted. 
            There are {0} clients connected to the server",
                    this.numConnectedSockets);

                if (!s.ReceiveAsync(readEventArgs))
                {
                    this.ProcessReceive(readEventArgs);
                }
            }
            else
            {
                Console.WriteLine("There are no more available sockets to allocate.");
            }
        }
        catch (SocketException ex)
        {
            Token token = e.UserToken as Token;
            Console.WriteLine("Error when processing data received from {0}:\r\n{1}", 
            token.Connection.RemoteEndPoint, ex.ToString());
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }

        // Accept the next connection request.
        this.StartAccept(e);
    }
}
Run Code Online (Sandbox Code Playgroud)

代码项目提供的代码示例:http : //www.codeproject.com/Articles/22918/How-To-Use-the-SocketAsyncEventArgs-Class