Reputation: 25
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
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