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