WSAEWOULDBLOCK error

hi all :)

Im having trouble with this error (WSAEWOULDBLOCK). It would be better if I start with the code which is:

Ive got a loop (its not really loop, but it is called every 1 milisecond) with two functions in it:
1
2
accept_connections();
receive_data();

accept connections isnt important here so Ill post a part of receivedata func()
1
2
3
4
5
6
for ( int i = 0; i < clients.size() && !clients[i].disconnecting; i++ ){
        if ( receive_client ( &clients[i], buffer, BUFSIZE ) ){
            if(buffer[1]==SIGN_COORDS) { clients[i].setCoords(buffer); send_all(); }
            ...
        }
    }


the problem is in function send_all():
1
2
3
4
5
6
7
8
9
for(int current=0; current<clients.size(); current++){
        for(int in=0; in<clients.size(); in++){
            if(in != current){
                char msg[BUFSIZE];
                ....
                send_data(&clients[current], msg, BUFSIZE);
            }
        }
    }


send_data() is just a function which sends msg to client whith size of BUFSIZE and handle errors and thats how I get the error WSAEWOULDBLOCK.

so how it works:
when the server receive a message that some player (client) has moved (changed its location) the server sends location of all players to all players through send_all() func. But after a time of running (about few seconds, 10-20) I get this error when sending data to some client and after a while again for another client until they are all disconnected.
The problem is that when I get this error I can send() messages to that client no more, but I dont know why when in the docs is written that it is non fatal error and also why it is running a while and then it starts with these errors... Also the client and the server both are non blocking

thanks for every reply :)
Last edited on
Also the client and the server both are non blocking


It is NOT an error by itself, it just means that no data is available in network buffers. You usually wait for a short period of time (using Sleep() or similar function) in a loop until data is available or connection is closed.
You need to use select() to detect when the socket is ready before accessing it.

http://www.cplusplus.com/forum/general/74473/#msg399304
Last edited on
I just started with server and in any code I have seen the function select used but only the FD_* macros... this is how I have them used:

1
2
3
4
5
6
class _client{
public:
    ...
    fd_set socket_data;
    ...
};


now in the accept_connections func which is in the loop is called function accept client which determinate if there is some new connection its looks like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
bool MainWindow::accept_client( ){
    _client newclient;
    newclient.address_length = sizeof ( sockaddr );
    newclient.socket = accept ( server_socket, ( sockaddr * ) &newclient.address, &newclient.address_length );
    if (error) {
     ..error handling
    }
    else{
        newclient.connected = true;
        clients.push_back(newclient);
        FD_ZERO ( &clients[clients.size()-1].socket_data );
        FD_SET ( clients[clients.size()-1].socket, &clients[clients.size()-1].socket_data );
        updateOnlineList();
        return true;
    }
    return false;
}


vector<_client> clients is variable which holds all connected clients

and theres function receive_data() where is called receive_client() func for every client
1
2
3
4
5
6
7
8
for ( int i = 0; i < clients.size() && !clients[i].disconnecting; i++ ){
        if ( receive_client ( &clients[i], buffer, BUFSIZE ) ){
            if(buffer[1]==SIGN_COORDS) { clients[i].setCoords(buffer); send_all(); }
            else if(buffer[1]==SIGN_DISCONNECT) disconnect_client(&clients[i]);
            else if(buffer[1]==SIGN_NICK) loginPlayer(&clients[i], buffer);
            buffer[0]='\0';
        }
    }


here comes the recieve_client func
1
2
3
4
5
6
7
8
9
10
11
12
13
int MainWindow::receive_client ( _client *current, char *buffer, int size )
{
    if ( FD_ISSET ( current->socket, &current->socket_data ) ){
        current->address_length = recv ( current->socket, buffer, size, 0 );
        . . .checking the buffer here
        if ( current->address_length == 0 ){
            disconnect_client( current );
            return false;
        }
        return true;
    }
    return false;
}


I do not see the error here but I have blind eyes oftem :D
It seems ok, apart from not calling select(). Can you remind me why you're using non-blocking sockets please.
Im making a game with a friend and I have to send position whenever some player/client moves so I dont know when it is... also later there will be more things I need send which wouldnt be send everytime the loop proceed so I cannot make client wait at the recv()
You need select() to detect when the socket is ready or reports an error. But you can also use select() on blocking sockets too. So I suggest you forget about non-blocking sockets.

What about the server waiting for accept()? You can use select on the listening socket too you know. It will be set for read when a client connects.

You need to use FD* macros with an fd_set, not on some arbitrary array of sockets.

I repeat, you can't test a socket for being ready with FD_ISSET unless the fd_set has been updated with select().

It may be worth stopping and reading this before continuing.
http://www.lowtek.com/sockets/select.html

Rowan836 is working on something similar, it may be work contacting him.
Thanks for amswers Ill see what I can do that after I read that :)
Ive looked at that article, but since I didnt understand much of the code still I havent used select function just made the client blocking so now I dont get that error since its ilogical :D

thanks for help :)
Topic archived. No new replies allowed.