Adam Olsson
Adam Olsson

Reputation: 32

First recv() cannot read message sent from server

I'm writing a simple TCP server and client where the server echoes back the message to the client. But I have a problem with the first read()/recv() call from the client side. Whenever a client connects to the server, it sends a welcome message, but I cannot display the welcome message on the client side. What i get in return from recv()/read() is 0, which indicates that the socket is closed or 0 bytes read. I know it isn't closed since the server echoes back messages but with a delay(example bellow). The read()/recv() works fine after I've written to the server from the client side. So my question is: Why does the first read()/recv() call receive return a 0?

TLDR; My client does not read()/recv() the welcome message sent from server. What am I doing wrong?

Server and client interaction(Notice empty 'Welcome message'): Server and client interaction

As you can see, the socket isn't closed so the only reason read()/recv() returns 0 is because 0 bytes read.

Client code:

(SETUP NOT INCLUDED)
printf("Connected. \n");

memset(buffer, 0, 1025);

/********* PROBLEM IS THIS READ()/RECV() **********/
n = recv(sockfd, buffer, strlen(buffer), NULL);
if(n == 0){ //
     //error("Error reading\n");
     printf("Error reading socket.");
}

printf("Welcome message: \n%s", buffer);

while(1){
    printf("\nPlease enter message: \n");

    memset(buffer, 0, 256);
    fgets(buffer, 255, stdin);
    printf("You sent: %s", buffer);

    n = write(sockfd, buffer, strlen(buffer));
    if(n <= 0)
    {
        error("Error writing socket. \n");
    }
    //om bye, break
    memset(buffer, 0, 256);
    //Läser här endast efter write
    n = read(sockfd, buffer, 255);
    if(n < 0)
    {
        error("Error reading from socket. \n");
    }

    printf("You received: %s", buffer);
}
//end while
close(sockfd);
return 0;

Relevant Server code:

 while(TRUE)
{
    /* Clear socket set */
    FD_ZERO(&readfds);
    /* Add master socket to set */
    FD_SET(masterSocket, &readfds);
    /* For now maxSd is highest */
    maxSd = masterSocket;

    /* Add child sockets to set, will be 0 first iteration */
    for(int i = 0; i < maxClients ; i++)
    {
        sd = clientSockets[i]; // sd = socket descriptor
        /* If valid socket descriptor */
        if(sd > 0)
        {
            FD_SET(sd, &readfds);
        }
        /* Get highest fd number, needed for the select function (later) */
        if(sd > maxSd)
        {   
            maxSd = sd;
        }
    }//end for-loop

    /* Wait for activity on any socket */
    activity = select(maxSd +1, &readfds, NULL, NULL, NULL);

    if((activity < 0) && (errno != EINTR))
    {
        printf("****** Error on select. ******\n"); //no need for exit.
    }

    /* If the bit for the file descriptor fd is set in the 
    file descriptor set pointed to by fdset */
    /* If something happend in the master socket, its a new connection */
    if(FD_ISSET(masterSocket, &readfds))
    {
        //står här och läser
        if((newSocket = accept(masterSocket, (struct sockaddr*)&address, (socklen_t*)&addrlen)) < 0)
        {
            perror("****** Could not accept new socket. ******\n");
            exit(EXIT_FAILURE);
        }

        /* Print info about connector */
        printf("New connection, socket fd is %d, ip is: %s, port: %d\n", newSocket, inet_ntoa(address.sin_addr), ntohs(address.sin_port));

        /**************** THIS IS THE WRITE THAT DOESN'T GET DISPLAYED ON CLIENT ******************/
        if( send(newSocket, message, strlen(message), 0) != strlen(message))
        {
             perror("****** Could not sent welcome message to new socket. ******\n");
        }

        puts("Welcome message sen successfully");

        /* Add new socket to array of clients */
        for(int i = 0; i < maxClients; i++)
        {
            if(clientSockets[i] == 0)
            {
                clientSockets[i] = newSocket;
                printf("Adding socket to list of client at index %d\n", i);
                break;
            }
        }
    }//end masterSocket if
    /* Else something happend at client side */
    for(int i = 0; i < maxClients; i++)
    {
        sd = clientSockets[i];

        if(FD_ISSET(sd, &readfds))
        {   
            /* Read socket, if it was closing, else read value */
            //denna read kan vara fel
            if((valread = read( sd, buffer, 1024)) == 0)
            {
                getpeername( sd, (struct sockaddr*)&address, (socklen_t*)&addrlen);
                printf("Host disconnected, ip %s, port %d.\n", inet_ntoa(address.sin_addr), ntohs(address.sin_port));

                close(sd);
                clientSockets[i] = 0;
            }
            else
            {
                buffer[valread] = '\0';
                send(sd, buffer, strlen(buffer), 0);
            }
        }
    }

I know this is a big wall of text but i am very thankful for anyone who takes their time with this problem.

Upvotes: 0

Views: 1406

Answers (2)

arrowd
arrowd

Reputation: 34421

The third arg to recv specifies a number bytes to read from the socket. And now look at your code:

memset(buffer, 0, 1025);
recv(sockfd, buffer, strlen(buffer), NULL);

First, you zero out whole buffer and then call strlen on it. No wonder it returns 0, as strlen counts non-zero bytes.

Instead, put the buffer length into a variable and use it everywhere:

const int bufSize = 1025;
memset(buffer, 0, bufSize);
recv(sockfd, buffer, bufSize, NULL);

Upvotes: 2

G.M.
G.M.

Reputation: 12898

I'm not sure if it's the sole cause of the issue but... in your client code you have...

memset(buffer, 0, 1025);

Then shortly after...

n = recv(sockfd, buffer, strlen(buffer), NULL);

strlen(buffer) at this point will return zero, so the call to recv does exactly what is requested -- it reads zero bytes.

Note also that the welcome message as sent by the server is not null terminated. Thus, your client has no way of knowing when the welcome message ends and the subsequent data begins.

Upvotes: 2

Related Questions