kernel_recvmsg有时会得到错误的数据

时间:2017-07-17 09:23:09

标签: c sockets recv unix-socket

我有一个模块,它分两部分接收数据。首先是一个无符号整数,表示下一步将遵循的数据长度。然后是数据本身。我在无限循环中执行以下操作

unsigned int z;
struct kvec vec;
struct msghdr msg;
while(1) {
    memset(&vec, 0, sizeof(vec));
    memset(&msg, 0, sizeof(msg));
    vec.iov_base = &z;
    vec.iov_len = sizeof(unsigned int);

    ret = kernel_recvmsg(client_socket, &msg, &vec, 1, vec.iov_len, 0);
    if(!z)
        break;
    data = kmalloc(z, GFP_KERNEL);
    if(!data)
        break;
    memset(&vec, 0, sizeof(vec));
    memset(&msg, 0, sizeof(msg));
    vec.iov_base = data;
    vec.iov_len = z;
    ret = kernel_recvmsg(client_socket, &msg, &vec, 1, vec.iov_len, 0);
    ...
    ...
    kfree(data);
}

编辑:由于接收不完整,我收到错误的数据。我的回复< vec.iov_len。有没有办法解决这个问题?

谢谢。

1 个答案:

答案 0 :(得分:0)

我通过更改标志来修复它。 这些链接将有所帮助

http://www.beej.us/guide/bgnet/output/html/multipage/recvman.html

http://elixir.free-electrons.com/linux/latest/source/include/linux/socket.h#L277

在第二个链接中,您可以找到所有可用的标志以及这些标志的子集的描述。我之前使用过标志字段为0,这意味着没有特别的选项,通过将其更改为MSG_WAITALL,命令在返回之前等待整个iov.len大小的消息。不完整的收到提前破坏了我的数据。