Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ server side not blocking on listen()

The code below doesn't block on listen(), it just finishes execution. Could you tell me why? (initWSA returns true, I checked it). I'm following a tutorial and I was told it should block because it's looking for clients to connect.

#include <iostream>
#include <WinSock2.h>

#pragma comment(lib, "ws2_32.lib")
using namespace std;

#define PORT 10000
bool initWSA(){
    WSADATA wsadata;
    int error = WSAStartup(0x0202, &wsadata);
    if (error) return false;
    if (wsadata.wVersion != 0x0202){
        WSACleanup();
        return false;
    }
    return true;
}
void closeConnection(SOCKET s)
{
    //Close the socket if it exists
    if (s)
        closesocket(s);

    WSACleanup(); //Clean up Winsock
}
int main(){
    initWSA();
    SOCKET s;
    SOCKADDR_IN addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(PORT);
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (s == INVALID_SOCKET) cout << "INVALID SOCKET" << endl;
    if (bind(s, (LPSOCKADDR)&addr, sizeof(addr)) == SOCKET_ERROR){
    cout << "SOCKET ERROR" << endl;
    }
    listen(s, SOMAXCONN);
    //cout << "CAUGHT ONE" << endl;
    //closeConnection(s);
    return 0;
}
like image 905
Greyshack Avatar asked Jun 29 '15 11:06

Greyshack


Video Answer


1 Answers

First of all, let's clarify the exact semantics of the listen() and accept() functions.

listen function:

The listen function places a socket in a state in which it is listening for an incoming connection.

Remarks:

To accept connections, a socket is first created with the socket function and bound to a local address with the bind function. A backlog for incoming connections is specified with listen, and then the connections are accepted with the accept function. Sockets that are connection oriented, those of type SOCK_STREAM for example, are used with listen. The socket s is put into passive mode where incoming connection requests are acknowledged and queued pending acceptance by the process.

accept function:

The accept function permits an incoming connection attempt on a socket.

Remarks:

The accept function extracts the first connection on the queue of pending connections on socket s. It then creates and returns a handle to the new socket. The newly created socket is the socket that will handle the actual connection; it has the same properties as socket s, including the asynchronous events registered with the WSAAsyncSelect or WSAEventSelect functions.

The accept function can block the caller until a connection is present if no pending connections are present on the queue, and the socket is marked as blocking. If the socket is marked as nonblocking and no pending connections are present on the queue, accept returns an error as described in the following. After the successful completion of accept returns a new socket handle, the accepted socket cannot be used to accept more connections. The original socket remains open and listens for new connection requests.

The appropriate example (source):

...
//----------------------
// Listen for incoming connection requests.
// on the created socket
if (listen(ListenSocket, 1) == SOCKET_ERROR) {
    wprintf(L"listen failed with error: %ld\n", WSAGetLastError());
    closesocket(ListenSocket);
    WSACleanup();
    return 1;
}
//----------------------
// Create a SOCKET for accepting incoming requests.
SOCKET AcceptSocket;
wprintf(L"Waiting for client to connect...\n");

//----------------------
// Accept the connection.
AcceptSocket = accept(ListenSocket, NULL, NULL);
if (AcceptSocket == INVALID_SOCKET) {
    wprintf(L"accept failed with error: %ld\n", WSAGetLastError());
    closesocket(ListenSocket);
    WSACleanup();
    return 1;
} else
    wprintf(L"Client connected.\n");

// No longer need server socket
closesocket(ListenSocket);
...
like image 170
Sergey Vyacheslavovich Brunov Avatar answered Sep 30 '22 01:09

Sergey Vyacheslavovich Brunov