c- recvfrom 错误 22

标签 c linux sockets linaro

好的,首先是代码:

int recvMast_sock;
struct sockaddr_in serv_addr, cli_addr;
socklen_t cli_len;
if ((recvMast_sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
  {
    critErr("listen:socket=");
  }

fillSockaddrAny(&serv_addr, UDP_NODE_LISTEN_PORT);// fills the sockaddr_in works fine elsewhere

if ((bind(recvMast_sock, (struct sockaddr*) &serv_addr, sizeof serv_addr)) < 0)
  {
    critErr("listen:bind recv_mast_sock:");
  }
recvReturn_i = recvfrom(recvMast_sock, &recvBuff[0], (size_t)1, 0, (struct   sockaddr*) &cli_addr, &cli_len);
if(recvReturn_i <0)
        printf("recv error%d\n",errno);

critErr 是一个处理错误的函数,它还包括错误的打印和 exit

这在线程中运行,如果有任何相关性的话。如果我在具有 ARM Cortex A9 和 Linaro Linux(基于精确的 Ubuntu)的 Zedboard(ZYNQ-7000 SoC)上编译并运行它。它打印错误 22 但在 recvBuff[0] 中仍然有接收到的值。

使用 xubuntu 在我的 VM 中运行它工作正常。

错误 22 等于 EINVAL,它被描述为无效参数。

recvfrom(2) 的联机帮助页中它声明 EINVAL 表示设置了 MSG_OOB 标志,但我没有使用任何标志(传递 0)。

在星期五离开之前,我开始了 apt-get 升级,因为我希望它是一个错误的库或类似的东西。我可以在星期一回来查看,但也许这里有人有其他想法出了什么问题。

最佳答案

在将 cli_len 传递给 recvfrom() 之前,您需要对其进行初始化:

cli_len = sizeof(cli_addr);

你没有初始化它,所以它有一个随机值。如果该值恰好是 <sizeof(cli_addr)recvfrom() 可能会因 EINVAL 而失败,或者至少会截断地址,因为它认为 cli_addr 不够大,无法接收客户端地址。如果该值远大于 sizeof(cli_addr)recvfrom() 可能会认为缓冲区超出了有效内存范围。

您必须告诉 recvfrom() cli_addr 实际上有多大。 documentation 中明确说明了这一点:

The argument addrlen is a value-result argument, which the caller should initialize before the call to the size of the buffer associated with src_addr, and modified on return to indicate the actual size of the source address. The returned address is truncated if the buffer provided is too small; in this case, addrlen will return a value greater than was supplied to the call.

所以你必须在调用recvfrom()之前用cli_addr的总大小初始化cli_len,然后调用recvfrom() 使用实际写入 cli_addr 的地址大小更新 cli_lencli_addr 可以大于地址,例如当使用 sockaddr_storage 结构在双栈套接字上接受 IPv4 或 IPv6 地址时。在问题的示例中,正在使用 IPv4 套接字,因此 cli_len 必须初始化为一个值 >= sizeof(sockaddr_in)

关于c- recvfrom 错误 22,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32921833/

相关文章:

linux - 在 linux bash 脚本中杀死一个 10 分钟的老僵尸进程

javascript - 回调函数缺少所需数据的范围

java - 为什么 socket.close() 不释放绑定(bind)端口?

c - 二分查找 C

linux - git中的破折号是什么?比如: -a -b -p

linux - 启动分区即将满: how to clear or extend it?

java - 网络编程中Java函数与C函数的等价

c++ - 如果x = 5,那么a =++ x *++ x如何给出49?

c - 如何在 C 中初始化双指针? (指针数组)

c - 排列方程中的项以隔离 C 中的 y 项