I am using ioctlsocket() function to make my socket non-blocking but when I call recvfrom(), I get the error 10035 ( WSAEWOULDBLOCK
).
u_long mode = 1;
ioctlsocket(newSocketIdentifier, FIONBIO, &mode);
while(1)
{
if((recv_len = recvfrom(newSocketIdentifier, receiveBuffer, sizeof(receiveBuffer), 0, (struct sockaddr *) &clientSocket, &clientSocketLength)) == SOCKET_ERROR)
{
char err[128];
itoa(WSAGetLastError(),err,10);
MessageBox( NULL,"Could not Receive Data",err,MB_ICONINFORMATION);
BREAK;
}
}
Can anybody explain why this happens? :(
This is normal if no data is available. The code is WSAEWOULDBLOCK (see this table) and means, that on a blocking port the function would have to sit and wait until it could be served.
while(1)
{
if((recv_len = recvfrom(newSocketIdentifier, receiveBuffer, sizeof(receiveBuffer), 0, (struct sockaddr *) &clientSocket, &clientSocketLength)) == SOCKET_ERROR)
{
int ierr= WSAGetLastError();
if (ierr==WSAEWOULDBLOCK) { // currently no data available
Sleep(50); // wait and try again
continue;
}
// Other errors
char err[128];
itoa(ierr,err,10);
MessageBox( NULL,"Could not Receive Data",err,MB_ICONINFORMATION);
break;
}
}
I cannot agree that this is "normal" like posted above.
In your call of recvfrom
you will receive an error in recv_len
. I recommend to check that value - it will be SOCKET_ERROR
and by calling WSAGetLastErrorenter
you will see error WSAEWOULDBLOCK
.
I am not a (Windows) socket expert, but based on my tests, I cannot use combination of ioctlsocket
and recvfrom
for receiving data via UDP in non-blocking mode (I did the same thing like you in your example).
I am planning to use combination of select
and recvfrom
with minimum possible timeout (1us). I do not know any other possibly better solution now.
Note: you should check also the return value of ioctlsocket
for possible error.
I will provide my code sample later today.
UPDATE (adding code as promised):
/* define list of sockets for function select(..) */
fd_set readfds;
/* define timeout for function select(..) */
TIMEVAL tv;
/* timeout: 1us */
tv.tv_usec = 1;
/* timeout: 0s */
tv.tv_sec = 0;
/* just 1 socket is used */
readfds.fd_count = 1;
readfds.fd_array[0] = receivingSocket;
/* determine the status of one or more sockets with timeout */
int selectReturnValue = select(0, &readfds, 0, 0, &tv);
/* check return value of the call of function select(..) */
switch (selectReturnValue)
{
/* select(..) function timeout */
case 0:
/* time limit expired */
break;
/* select(..) function error */
case SOCKET_ERROR:
/* check the error status for the last windows sockets operation */
selectError(WSAGetLastError());
break;
/* no timeout and no error */
default:
/* receive data from UDP */
resultOfrecvfrom = recvfrom(receivingSocket, receivingBuffer, sizeof(receivingBuffer), 0, (SOCKADDR *)&serverReceptionInfo, &serverReceptionInfoLength);
/* check result of call of recvfrom(..) */
switch (resultOfrecvfrom)
{
/* connection has been gracefully closed */
case 0:
/* socket was closed */
break;
/* socket error occurred during last call of socket operation */
case SOCKET_ERROR:
/* check the error status for the last Windows Sockets operation */
recvfromError(WSAGetLastError());
break;
/* resultOfrecvfrom amount of data received */
default:
/* ... add your code here */
break;
}
break;
}
I just copied crucial part of my code if more is needed, let me know in comments.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.