C ++ server does not block listening ()
The code below doesn't block while listening (), it just exits. Could you tell me why? (initWSA returns true, I checked it). I am following the tutorial and I was told that it should block because it is 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;
}
source to share
First of all, let's clarify the exact semantics of the functions listen()
and accept()
.
listening function :
The listener function puts the socket in a state where it is listening for an incoming connection.
Note:
To accept connections, a socket is first created using the socket function and bound to a local address using the bind function . The delay for incoming connections is set using listen , and then connections are accepted using the accept function . Connection oriented sockets such as SOCK_STREAM , for example, are used when listening . Socket s is placed in passive mode, where incoming connection requests are acknowledged and queued until accepted by the process.
accept function :
The accept function allows an incoming socket connection attempt.
Note:
The accept function retrieves the first connection in the pending queue on socket s. It then creates and returns a handle to the new socket. The socket created is the socket that will handle the actual connection; it has the same properties as socket s, including asynchronous events registered with WSAAsyncSelect or WSAEventSelect .
The accept function can block the caller until a connection appears if pending connections are not queued and the socket is marked blocking. If the socket is marked non-blocking and no pending connections are present in the queue, accept returns an error, as described below. Upon successful completion, accept returns a new socket descriptor, the accepted socket cannot be used to accept more connections. The original socket remains open and listens for new connection requests.
Relevant 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);
...
source to share