send - recv 无法按预期使用命令行参数
send - recv not working as expected with command line arguments
我正在从客户端的发送函数中一个一个地传递 cmd 参数,如下所示:
for( i = 3; i < argc; i++)
{
//memset(buffer, '[=10=]', 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;
}
}
这是 recv 的服务器端代码:
for( j = 0; j < arg_no; j++)
{
//memset(buffer, '[=11=]', sizeof(buffer));
bzero(buffer, sizeof(buffer));
n = recv(clientfd, buffer, sizeof(buffer), 0);
if(n <= 0)
{
showerror("Error in reading2 : ", clientfd);
break;
}
}
我在这里面临的问题是整个 **argv 都通过了
一次,然后等待 recv,导致程序停止。我什至尝试通过将参数复制到缓冲区然后发送(注释代码)来传递参数,但它不起作用。
TCP 是基于流的,而不是基于消息的。这意味着 send
和 recv
调用之间没有一对一的相关性。正如您的情况显然发生的那样,有可能将多个 send
调用合并为一个 recv
调用。
为了解决这个问题,您的应用程序需要定义某种消息边界。例如,您可以首先传递期望的字符串数,然后为每个字符串传递长度,后跟实际字符串。
在发件人方面,您将拥有以下内容:
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;
}
}
然后在接收方:
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;
}
}
我正在从客户端的发送函数中一个一个地传递 cmd 参数,如下所示:
for( i = 3; i < argc; i++)
{
//memset(buffer, '[=10=]', 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;
}
}
这是 recv 的服务器端代码:
for( j = 0; j < arg_no; j++)
{
//memset(buffer, '[=11=]', sizeof(buffer));
bzero(buffer, sizeof(buffer));
n = recv(clientfd, buffer, sizeof(buffer), 0);
if(n <= 0)
{
showerror("Error in reading2 : ", clientfd);
break;
}
}
我在这里面临的问题是整个 **argv 都通过了 一次,然后等待 recv,导致程序停止。我什至尝试通过将参数复制到缓冲区然后发送(注释代码)来传递参数,但它不起作用。
TCP 是基于流的,而不是基于消息的。这意味着 send
和 recv
调用之间没有一对一的相关性。正如您的情况显然发生的那样,有可能将多个 send
调用合并为一个 recv
调用。
为了解决这个问题,您的应用程序需要定义某种消息边界。例如,您可以首先传递期望的字符串数,然后为每个字符串传递长度,后跟实际字符串。
在发件人方面,您将拥有以下内容:
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;
}
}
然后在接收方:
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;
}
}