C++ Socket Blocking issue

The server waits for a connection, once there is a connection, it sets the socket to non-blocking. That takes place in the first if statement, to check the vector for the size, if there isn't a connection then it continues to the loop which reads all the current connections and listens for new connections. Everything works fine until another connection connects, it accepts it, and then waits for more connection, as if it was a blocking socket, although its a non-blocking socket.

Can anyone tell me whats wrong?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
void Server::Listen() {

    listen(mSocket, 5);

    cout << "Listening." << endl;

    while(1) {

        const int size = 512;
        char buffer[size+1];
        int status;
        int flags;

        if(mConnectionPool.size() < 1) {

            mConnection = accept(mSocket, (struct sockaddr*)(&server), &mSize);
            if(mConnection != -1) {
                mConnectionPool.push_back(mConnection);
                cout << "Connection " << mConnection << " handled and added." << endl;
                cout << "Size of connection pool: " << mConnectionPool.size() << endl;

                flags = fcntl(mConnection, F_GETFL, 0);
                fcntl(mConnection, F_SETFL, flags | O_NONBLOCK);
                flags = fcntl(mSocket, F_GETFL, 0);
                fcntl(mSocket, F_SETFL, flags | O_NONBLOCK);
            }

        } else if(mConnectionPool.size() > 0) {


            //ERROR OCCURS HERE
            if(mConnection = accept(mSocket, (struct sockaddr*)(&server), &mSize)!= -1) {
                mConnectionPool.push_back(mConnection);
                cout << "Connection handled and added." << endl;
                cout << "Size of connection pool: " << mConnectionPool.size() << endl;
                continue;
            }

            for(int i = 0; i < mConnectionPool.size(); i++) {

                status = read(mConnectionPool[i], buffer, size);

                if(status > 0) {
                    cout << "Handling message: " << buffer << " dispatching to connection " << mConnectionPool[i] << endl;
                    int sentstat = send(mConnectionPool[i], &buffer, (socklen_t)sizeof(buffer), 0);
                    cout << sentstat << endl;

                } else if(status == 0) {
                    mConnectionPool.erase(mConnectionPool.begin(), mConnectionPool.begin() + i + 1);
                    cout << "Connection " << mConnectionPool[i] << " Erased." << endl;
                    continue;
                } else if(status < 0) {
                    continue;
                }
            }

        }
                
    }
}
Last edited on
I would expect accept to block because mSocket is a blocking socket.

The conventional way to do this is to use non-blocking sockets with select.
But when it recv's its first connection, it sets the socket to non-blocking, so shouldn't it be a non-blocking socket?
oh ok, thank you kbw, I will look into the select method.
Last edited on
You are dealing with more than one socket here. Your server socket (mSocket) is still blocking and is never set to non-blocking. The socket that you set to non-blocking (mConnection) is the socket that is opened by your (blocking) select() function.

If you want to use non-blocking sockets then I think select() is, indeed, the best way to do it.
I got it to work! Thank you guys!
Have you changes the above code, because I can see there that both sockets are set to non-blocking:
flags = fcntl(mConnection, F_GETFL, 0);
fcntl(mConnection, F_SETFL, flags | O_NONBLOCK);
flags = fcntl(mSocket, F_GETFL, 0);
fcntl(mSocket, F_SETFL, flags | O_NONBLOCK);

If not changed then what was your solution?
Topic archived. No new replies allowed.