Non-blocking socket operation cannot be performed immediately on send
I am writing a server for a game and I want to be able to handle thousands of concurrent users. For this reason, I went with non-blocking sockets and used the polling method. However, I am creating multiple threads to handle databases and web calls, and some of those threads will send a response to the user. On one of these threads, when I submit, I receive the error "Nonblocking socket operation could not be performed immediately." What could be causing this problem? I am assuming this because the poll happens at the same time as the call to send. If I used beginAsync, would this error stop? I was thinking about blocking a socket, but I don't want my main thread to be blocked for this.
source to share
I don't know what non-blocking-polling socket calls you are using, but I would recommend using Async socket calls (instead of Begin). For more information on the difference between Async vs Begin calls, see: What is the difference between BeginConnect and ConnectAsync?
Asynchronous calls will automatically "poll" at the OS level, which will be much more efficient than your polling. In fact, they use I / O completion ports, which are probably the fastest and most efficient thing you can use on Windows to handle a lot of client connections / requests.
As far as the error goes, I would think this is normal non-blocking socket operation, so you just need to handle it gracefully.
Update
Perhaps your server should do something like this:
// 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);
}
}
Sample code provided by the code project: http://www.codeproject.com/Articles/22918/How-To-Use-the-SocketAsyncEventArgs-Class
source to share
When a non-blocking socket tries to read data but finds nothing, you will get this error: The socket would like to wait for data but cannot, because it must return immediately, being non-blocking.
I suggest you switch to blocking sockets, figure out why the data is missing, adjust accordingly, and then switch back to non-blocking. Or you can handle the error and retry the operation.
source to share
I was also getting this exception when submitting data and just found a solution.
You are getting an exception because the socket send buffer is full. Since you are trying to send data using a non-blocking dispatch, an exception is thrown so you know you MUST send it using a blocking dispatch.
No data is sent after an exception is thrown, so you must resubmit it. Your custom challenge to challenge now becomes:
try
{
m_socket.Send(buffer, bufferSize, SocketFlags.None);
}
catch (SocketException e)
{
if(e.SocketErrorCode == WouldBlock)
{
m_socket.Blocking = true;
m_socket.Send(buffer, bufferSize, SocketFlags.None);
m_socket.Blocking = false;
}
}
It would be nice to increase the SendBufferSize socket. By default I think it is 8kb. For my needs, I had to increase it to 2MB, and then the "Send" call no longer threw this exception.
source to share
This exception is too general. On MSDN,
If you receive a SocketException, use the SocketException.ErrorCode property to get the specific error code. After you receive this code, refer to the documentation for Windows Sockets version 2 error codes in the MSDN Library for a detailed description of the error.
The socket error codes are here .
source to share