【问题标题】:Invalid argument from sendto in ansi C when trying to implement UDP尝试实现 UDP 时,ansi C 中 sendto 的参数无效
【发布时间】:2013-09-18 17:21:38
【问题描述】:

我知道关于 SO 有一些类似的问题,但我觉得每个人都有不同的问题导致此问题。所以我发布了我的特殊情况。

我正在使用 raspbian(一种 debian 衍生产品)开发树莓派。我正在用 ansi C 编写代码。这是一个服务器,它通过端口 500 将一些数据发送到另一端的 udp 客户端。

#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
int main()
{
   int sockfd;
   struct sockaddr_in servaddr,cliaddr;
   socklen_t clilen;
   char buffer[256];

   sockfd=socket(AF_INET,SOCK_DGRAM,0);

   bzero(&servaddr,sizeof(servaddr));
   servaddr.sin_family = AF_INET;
   servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
   servaddr.sin_port=htons(500);
   bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
   sprintf(buffer,"hi this is a test \n");
   if(sendto(sockfd,buffer,sizeof(buffer),0,(struct sockaddr *)&cliaddr,sizeof(cliaddr))==-1)
   { error("fail:")
    };

   return 0;
}

但这只是给了我“无效参数”的错误,我无法弄清楚可能是什么错误。如果我提供给 sendto 的参数类型不正确,这将在编译时失败。但是类型是正确的并且可以编译,只有在运行时才会失败。

【问题讨论】:

  • 与参数类型无关。 sockfd 例如可以是任何整数,即使该整数不引用套接字。因此,您的代码将编译,但您会在运行时收到错误。

标签: c udp debian-based


【解决方案1】:

cliaddr 结构没有初始化。因此,它的内容是随机的。你的代码编译得很好,因为你有一个 struct sockaddr_in 它应该在哪里,但是编译器无法检查你是否已经正确初始化它。

另一方面,在运行时sendto 被调用glibc 或内核发现cliaddr 结构中的随机数据看起来不是有效地址并抛出invalid argument错误。

解决方案:在使用cliaddr变量之前对其进行初始化。

编辑:您还需要正确初始化套接字,第三个参数不应该是0

第二次编辑,read me:对于资源,我推荐the extraordinary guide of Beej。对于您的确切问题this 子章节可以提供帮助。

【讨论】:

  • 如何初始化 cliaddr 结构?我一直在努力寻找一个好的示例代码,似乎当前的代码完全让我误入歧途。
  • 查看第二次编辑中的链接。这是一个很好的教程,你甚至有例子。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-07
  • 2018-06-16
  • 1970-01-01
  • 2018-10-11
  • 2014-01-04
  • 2015-12-07
  • 1970-01-01
相关资源
最近更新 更多