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 是基于流的,而不是基于消息的。这意味着 sendrecv 调用之间没有一对一的相关性。正如您的情况显然发生的那样,有可能将多个 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;
                }

          }