Question

I have a server that spawns a thread for each client that connects to it. The thread then deals with receiving/sending data to the client. Here is my server code:

    //////////////
    //  START   //
    /////////////
    while( 1 )
    {
    if( listen(serverSocket, SOMAXCONN) == SOCKET_ERROR ) 
    {
        printf( "Listen failed with error: %ld\n", WSAGetLastError() );
        break;
    }    
        /*
         *  wait for clients...
        */
        clientSocket = accept(serverSocket,
                              (struct sockaddr *)&clientSockAddr,
                              &clientSockAddrLen);


        if( clientSocket == INVALID_SOCKET )
        {
            printf("%d:accept failed\n", WSAGetLastError());
            closesocket(serverSocket);
            WSACleanup();
            return 1;
        }

        printf("Client accepted: IP: %s PORT: %d\n",
            inet_ntoa(clientSockAddr.sin_addr),
            clientSockAddr.sin_port );

        THREADDATA threadData = { clientSocket };
        sprintf_s(threadData.ip, "%s", inet_ntoa(clientSockAddr.sin_addr));

        // spawn a thread for each client
        hthread = CreateThread(
                    NULL,                       // don't inherit handle
                    0,                          // use default size for the executable
                    processClient,
                    (pTHREADDATA)&threadData,   // thread data
                    0,                          // run right away
                    &threadId );
    }

And here is what my thread function looks like:

/*
    called by thread for each client
*/
DWORD WINAPI processClient(LPVOID lpParam)
{
    int numBytesRecvd = 0,
        numBytesSent = 0,
        index = 0,
        nLeft = SIZE,
        TOTAL = SIZE;

    char buff[SIZE];
    int run = 1;

    char msg[MSG_SIZE];

    pTHREADDATA td = (pTHREADDATA)lpParam;

    /* keep processing client */
    while (run)
    {
        memset(buff, 0, SIZE);

        numBytesRecvd = recv(td->clientSocket, buff, nLeft, 0);


        /* CLIENT EXITED */
        if( !strcmp(buff, "exit") )
        {

            printf("Client exited!\n");

            run = 0;
        }

        if( numBytesRecvd > 0 )
        {

            printf("< %s\n", buff);

        }

        if (numBytesRecvd == 0)
        {
            printf("Client closed!\n");
            run = 0;
        }

        if( numBytesRecvd == SOCKET_ERROR )
        {
            printf("%d:Recieve error!\n", WSAGetLastError());
            run = 0;
        }
    }

    closesocket(td->clientSocket);
    ExitThread(0);

    return 0;
}

Issue:

So I start the server and the client, say client1 (from command prompt in win 7), everything is fine. When I type something at the client1 terminal, it is printed at the server terminal.

Now I launch another client, client2, it gets connected to the server and whatever I type gets displayed at the server, but now when I type something at client1 it doesn't get displayed at the server terminal.

So basically every time I start a new client, only that client can talk to the server, the old clients cannot!!! But I thought the thread will keep handling each client? Or is it that cmd prompt in windows is not thread safe?

Was it helpful?

Solution

I can see two probable issues here : 1) You are passing threadData on the stack to a different thread. You should be allocating it on the heap and then pass it to the thread. 2)I think you are not assigning clientSocket correctly to threadData, shouldnt you be assigning to a member of the structure threadData?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top