【问题标题】:Unix domain socket error, sendmsg: No buffer space availableUnix 域套接字错误,sendmsg:没有可用的缓冲区空间
【发布时间】:2018-03-11 10:47:19
【问题描述】:

我有一个很简单的sn-p代码,试试看unix域socket是怎么工作的,我写了sender函数,还没有receiver函数,如下:

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>
#define ERR_EXIT(m) { \
        perror(m); \
        exit(EXIT_FAILURE); \
    }

void send_fd(int sock_fd, int number){
    iovec vec;
    vec.iov_base = &number;
    vec.iov_len = sizeof(number);

    msghdr msg;
    msg.msg_name = NULL;
    msg.msg_namelen = 0;
    msg.msg_iov = &vec;
    msg.msg_iovlen = 1;
    msg.msg_flags = 0;

    int ret = sendmsg(sock_fd, &msg, 0);
    if (ret != 1)
        ERR_EXIT("sendmsg");
}

int main(void){
    int sockfds[2];
    if (socketpair(PF_UNIX, SOCK_STREAM, 0, sockfds) < 0)
        ERR_EXIT("socketpair");
    send_fd(sockfds[1], 20);
    return 0;
}

在 linux 上编译并运行它,它会打印:

sendmsg: No buffer space available

嗯,我自己没有打印这条消息,猜它是由 sendmsg 自己打印的。我的程序哪里出错了?我用谷歌搜索了一段时间并检查了这个网站,没有找到好的线索。

如何解决?谢谢。

是的,应该添加 msghrd msg={0};初始化,问题解决!

【问题讨论】:

  • 输出确实是由您的代码打印的,来自ERR_EXIT 宏及其对perror 的使用。
  • 为什么将返回值与 1 进行比较?没有有效的errno 集可以是-1 以外的任何内容。
  • 你忘了说代码需要用C++编译器编译。
  • @EugeneSh。可能是因为结构变量的定义没有struct 关键字。
  • @EugeneSh。您可能还应该写一个关于该比较的答案,因为它是 OP 问题的原因(因为 sendmsg 返回发送的 bytes 数,而不是消息数)。跨度>

标签: c linux sockets unix dns


【解决方案1】:

msghdr初始化后需要添加memset:

msghdr msg;
memset(&msg, 0, sizeof(msg));

问题在于 C(和 C++,除非它们有构造函数)中的局部变量没有被初始化。您只初始化了一些字段,但不是全部。结果是其他一些人(我怀疑msg_control)在其中包含垃圾,导致您目睹的错误。

除了那个问题,其他人在cmets上说的也是真的。错误代码是 -1(或者,更好的是 &lt;0)。

【讨论】:

  • 使用&lt; 0 比较是有效的,但sendmsg 被指定在错误时返回-1(与大多数其他POSIX 系统调用一样),所以它并不是真的“更好”。
  • 我们可以同意这是一个品味问题吗?
猜你喜欢
  • 1970-01-01
  • 2011-05-25
  • 2012-04-26
  • 2018-08-29
  • 2016-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-13
相关资源
最近更新 更多