sendmsg 得到了错误的地址

sendmsg got Bad address

在学习网络编程(TCP)的时候遇到了这个问题: 我尝试使用 sendmsg() 和 recvmsg() 在客户端和服务器之间交换信息,但是 "sendmsg()" 出现错误 "BAD ADDRESS".
Whosebug上的一些答案提到了内存问题,但我仍然很困惑,不知道该怎么办。 这是代码(相关部分)和结果。 如果有人能帮我解决这个问题,我将不胜感激。

void process_conn_server(int s) //s is the socketfd
{
    char buffer[30];
    ssize_t size = 0;
    struct msghdr msg;

    struct iovec *v = (struct iovec *)malloc(3 * sizeof(struct iovec));
    if (!v)
    {
        perror("wrong: allocate memory\n");
        return;
    }

    msg.msg_name = NULL;
    msg.msg_namelen = 0;
    msg.msg_control = NULL;
    msg.msg_controllen = 0;
    msg.msg_iov = v;
    msg.msg_iovlen = 30;
    msg.msg_flags = 0;

    // vs = v;
    v[0].iov_base = buffer;
    v[1].iov_base = buffer + 10;
    v[2].iov_base = buffer + 20;
    v[0].iov_len = v[1].iov_len = v[2].iov_len = 10;

    for (;;)
    {
        size = recvmsg(s, &msg, 0);
        if (size == 0)
        {
            return;
        }

        sprintf(v[0].iov_base, "%d ", size);
        sprintf(v[1].iov_base, "bytes alt");
        sprintf(v[2].iov_base, "ogether\n");

        v[0].iov_len = strlen(v[0].iov_base);
        v[1].iov_len = strlen(v[1].iov_base);
        v[2].iov_len = strlen(v[2].iov_base);

        sendmsg(s, &msg, 0);
    }
}
void process_conn_client(int s)
{
    char buffer[30];
    ssize_t size = 0;
    struct msghdr msg;

    struct iovec *v = (struct iovec *)malloc(3 * sizeof(struct iovec));
    if (!v)
    {
        perror("wrong: allocate memory\n");
        return;
    }

    msg.msg_name = NULL;
    msg.msg_namelen = 0;
    msg.msg_control = NULL;
    msg.msg_controllen = 0;
    msg.msg_iov = v;
    msg.msg_iovlen = 30;
    msg.msg_flags = 0;

    // vc = v;
    v[0].iov_base = buffer;
    v[1].iov_base = buffer + 10;
    v[2].iov_base = buffer + 20;
    v[0].iov_len = v[1].iov_len = v[2].iov_len = 10;

    // int fd;
    for (;;)
    {
        // fd = open("firstfile.txt", O_RDONLY, 0666);
        size = read(0, v[0].iov_base, 10);
        printf("%d size\n", size);
        if (size > 0)
        {
            //读到数据,发送给服务器
            v[0].iov_len = size;

            if (sendmsg(s, &msg, 0) < 0)
            {
                perror("");
                return;
            }

            v[0].iov_len = v[1].iov_len = v[2].iov_len = 10;
            size = recvmsg(s, &msg, 0);

            for (int i = 0; i < 3; i++)
            {
                if (v[i].iov_len > 0)
                {
                    write(1, v[i].iov_base, v[i].iov_len);
                }
            }
        }
    }
}

结果:
(base)qin@qin-D~/JuniorB/NetworkProgramming/7master●./client 127.0.0.1
你好
6码
地址错误

其他部分应该是正确的。(我没有在这里上传,因为它们有点长)。当我使用下面的 2 个函数时,这就是我得到的(也是我想要的):

void process_conn_client1(int s)
{
    char buffer[30];
    ssize_t size = 0;
    //申请三块结构类型
    struct iovec *v = (struct iovec *)malloc(3 * sizeof(struct iovec));
    if (!v)
    {
        printf("Not enough memory\n");
        return;
    }

    vc = v;
    //挂接全局变量,便于释放管理

    v[0].iov_base = buffer;
    v[1].iov_base = buffer + 10;
    v[2].iov_base = buffer + 20;
    v[0].iov_len = v[1].iov_len = v[2].iov_len = 10;

    int i = 0;
    for (;;)
    {
        size = read(0, v[0].iov_base, 10);
        if (size > 0)
        {
            //读到数据,发送给服务器
            v[0].iov_len = size;
            writev(s, v, 1);

            v[0].iov_len = v[1].iov_len = v[2].iov_len = 10;
            size = readv(s, v, 3);

            for (i = 0; i < 3; i++)
            {
                if (v[i].iov_len > 0)
                {
                    write(1, v[i].iov_base, v[i].iov_len);
                }
            }
        }
    }
}


    void process_conn_server1(int s)
{
    char buffer[30];
    ssize_t size = 0;
    //申请三块结构类型
    struct iovec *v = (struct iovec *)malloc(3 * sizeof(struct iovec));
    if (!v)
    {
        printf("Not enough memory\n");
        return;
    }

    vs = v;
    v[0].iov_base = buffer;
    v[1].iov_base = buffer + 10;
    v[2].iov_base = buffer + 20;
    v[0].iov_len = v[1].iov_len = v[2].iov_len = 10;

    for (;;)
    {
        size = readv(s, v, 3);
        if (size == 0)
        {
            return;
        }
        sprintf(v[0].iov_base, "%d ", size);
        sprintf(v[1].iov_base, "bytes alt");
        sprintf(v[2].iov_base, "ogether\n");

        v[0].iov_len = strlen(v[0].iov_base);
        v[1].iov_len = strlen(v[1].iov_base);
        v[2].iov_len = strlen(v[2].iov_base);

        writev(s, v, 3);
    }
}

结果:
(base)qin@qin-D~/JuniorB/NetworkProgramming/7master●./client 127.0.0.1
你好
一共6个字节
输入此行和服务器 returns 长度
总共 10 个字节
总共 10 个字节
总共 10 个字节
总共 10 个字节
一共6个字节

"sendmsg()" got error "BAD ADDRESS".

对于process_conn_client中的第一种情况,只需替换

msg.msg_iovlen = 30;

来自

 msg.msg_iovlen = 3;

因为 v 包含 3 个条目而不是 30 个(可能你放 30 是因为 10 有 3 个缓冲区)


除此之外还在 process_conn_client 因为你只从 stdin doing[=16= 读取最多 10 个字符]

size = read(0, v[0].iov_base, 10);

只有发送缓冲区的第一部分可以初始化,后面的两个在发送时不会初始化