Search code examples
c++socketstcp

C++ - Socket Programming - Multithreaded program throws Fatal program exit requested


I'm working on a TCP server where it receives image data from a mobile app and does some image processing on it. I managed to open a socket and receive the data successfully. However, the problem occurs when trying to run multiple threads to receive multiple connections simultaneously.

The approach I'm taking is to create a ListenSocket on the main thread, which accepts connections and passes them to a thread each time a connection is requested. These are some code snippets:

Main function:

serverInitilization(iResult, wsaData, hints, result, ClientSocket, ListenSocket);
std::vector<FaceLandmarks> landmarks;
std::vector<std::vector<float>> features;
//main server loop
while(true)
{
    cout << "Listening for connection...\n";
    // Accept a client socket
    ClientSocket = accept(ListenSocket, NULL, NULL);
    if (ClientSocket == INVALID_SOCKET) {
        printf("accept failed with error: %d\n", WSAGetLastError());
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }

    cout << "Got connection!\n";
    numConn++;

    thread t(recThread, ClientSocket);
    cout << "Thread started. Back to listening...\n";
    //t.join();
} 


// shutdown the connection & cleanup
closeSocketConnection(iResult, ListenSocket);
// cleanup
return 0;

serverInitialization:

void serverInitilization(int iResult, WSADATA socketData, struct addrinfo hints
, struct addrinfo* result, SOCKET& ClientSocket, SOCKET& ListenSocket){
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &socketData);
if (iResult != 0) {
    printf("WSAStartup failed with error: %d\n", iResult);
    return;
}

ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;

// Resolve the server address and port
iResult = getaddrinfo(DEFAULT_SERVER_IP, DEFAULT_PORT, &hints, &result);
if (iResult != 0) {
    printf("getaddrinfo failed with error: %d\n", iResult);
    WSACleanup();
    return;
}

// Create a SOCKET for connecting to server
ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ListenSocket == INVALID_SOCKET) {
    printf("socket failed with error: %ld\n", WSAGetLastError());
    freeaddrinfo(result);
    WSACleanup();
    return;
}
// Setup the TCP listening socket
iResult = ::bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR) {
    printf("bind failed with error: %d\n", WSAGetLastError());
    freeaddrinfo(result);
    closesocket(ListenSocket);
    WSACleanup();
    return;
}

freeaddrinfo(result);

iResult = listen(ListenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR) {
    printf("listen failed with error: %d\n", WSAGetLastError());
    closesocket(ListenSocket);
    WSACleanup();
    return;
}

}

and finally, the thread function:

void recThread(SOCKET client){
cout << "Connected in thread number: " << numConn << endl;

SOCKET current_client = client;

char recievingBuffer[DEFAULT_BUFLEN];
int recievingBufferLength = DEFAULT_BUFLEN;
int res;

while (1)
{
    res = recv(current_client, recievingBuffer, recievingBufferLength, 0);

    Sleep(10);

    if (res == 0)
    {
        MessageBox(0, "error", "error", MB_OK);
        closeSocketConnection(res, current_client);
        break;
    }
    else {
        printf("Bytes received: %d\n", res);
        printf("Data received: ");
        printf(recievingBuffer);
        printf("\n");
    }
}

closeSocketConnection(res, current_client);

}

Now, the first connection is handled with no problems. However, when the server tries to listen again, I get this exception:

Unhandled exception at 0x00007FFF37274A30 (msvcr120.dll) in serverSideApp.exe: Fatal program exit requested.

When debugging, I could find that the cause of this problem happens here:

ClientSocket = accept(ListenSocket, NULL, NULL);

At this line, in the second iteration of the while loop. Can someone help me with this error and tell me what am I doing wrong? I built this code from various examples online and with my understanding of threading and socket programming.

Any help will be much appreciated, thanks in advance!


Solution

  • I fixed it by using t.detach() instead of t.join(). The join() function stops the main thread until the thread is done executing. However, detach() separates the thread from the main thread totally, so that it can run totally independently from the main thread.

    I'll keep my answers and questions since multithreaded TCP programming took me some time to get working well, so maybe someone will find it useful later.