Ankit Negi
Ankit Negi

Reputation: 25

send - recv not working as expected with command line arguments

I am passing cmd arguments one by one from send function from clients like this :

    for( i = 3; i < argc; i++)
    {
            //memset(buffer, '\0', sizeof(buffer));
            //bzero(buffer, sizeof(buffer));
            //strcpy(buffer, argv[i]);
            n = send(sockfd, argv[i], strlen(argv[i]), 0);
            //n = send(sockfd, buffer, strlen(buffer), 0);
            if(n <= 0 )
            {
                    perror("Error in writing2 : ", sockfd);
                    return FAILURE;
            }
    }

here's the server side code for recv :

            for( j = 0; j < arg_no; j++)
            {
                    //memset(buffer, '\0', sizeof(buffer));
                    bzero(buffer, sizeof(buffer));
                    n = recv(clientfd, buffer, sizeof(buffer), 0);
                    if(n <= 0)
                    {
                             showerror("Error in reading2 : ", clientfd);
                             break;
                    }

              }

The problem I am facing here is that whole of the **argv is getting passed once and its waiting for recv after that, causing the program to halt. I even tried passing arguments by copying it to a buffer and then sending(commented code), but it din't work.

Upvotes: 1

Views: 134

Answers (1)

dbush
dbush

Reputation: 223897

TCP is stream based, not message based. That means that there is not a one-to-one correlation between send and recv calls. It's possible, as is apparently happening in your case, that multiple send calls are consolidated into a single recv call.

To account for this, your application needs to define some kind of message boundary. You could, for example, first pass the number of strings to expect, then for each string pass the length followed by the actual string.

On the sender side, you would have the following:

char numargs = argc - 3;
// send the number of strings to expect
n = send(sockfd, &numargs, sizeof(numargs), 0);
if(n <= 0 )
{
        showerror("Error in writing2 : ", sockfd);
        return FAILURE;
}
for( i = 3; i < argc; i++)
{
        // send the string length
        char len = strlen(argv[i]);
        n = send(sockfd, &len, sizeof(len), 0);
        if(n <= 0 )
        {
                showerror("Error in writing2 : ", sockfd);
                return FAILURE;
        }
        n = send(sockfd, argv[i], strlen(argv[i]), 0);
        if(n <= 0 )
        {
                showerror("Error in writing2 : ", sockfd);
                return FAILURE;
        }
}

Then on the receiving side:

char numargs;
// get the number of strings to expect
n = recv(clientfd, &numargs, sizeof(numargs), MSG_WAITALL);
if(n <= 0 )
{
        showerror("Error in reading2 : ", clientfd);
        return FAILURE;
}

        for( j = 0; j < numargs; j++)
        {
                char len;
                // get the string length
                n = recv(clientfd, &len, sizeof(len), MSG_WAITALL);
                if(n <= 0)
                {
                         showerror("Error in reading2 : ", clientfd);
                         break;
                }
                bzero(buffer, sizeof(buffer));
                // get the string
                n = recv(clientfd, buffer, len, MSG_WAITALL);
                if(n <= 0)
                {
                         showerror("Error in reading2 : ", clientfd);
                         break;
                }

          }

Upvotes: 1

Related Questions