c - send - recv 无法按预期使用命令行参数

标签 c sockets send recv

我像这样从客户端的发送函数中一个一个地传递 cmd 参数:

    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;
            }
    }

这是 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;
                    }

              }

我在这里面临的问题是整个 **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;
                }

          }

关于c - send - recv 无法按预期使用命令行参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49836256/

相关文章:

c - Execvp 与 "ls -l | wc"一起工作,但因“ls -l|wc”而失败

c - "stack smashing detected"消息打印到哪个流?

MAMP Pro 上的 MySQL 连接被拒绝

Android: Action_Send return Extra_Stream: 如何获取文件的扩展名

Python 将变量从一个脚本发送到另一个脚本

c - 如何将 0 到 25 之间的整数转换为对应的 ASCII 字符?

c - 如何让一个函数返回多个值?

c - 在套接字编程中消息未从服务器发送到客户端

java - android服务器如何知道客户端断开连接或关闭

python - 用 python 发送电子邮件