【问题标题】:recvfrom() always return zero remote addressrecvfrom() 总是返回零远程地址
【发布时间】:2016-05-17 20:57:56
【问题描述】:

我正在编写一个简单的 udp 服务器应用程序,当我尝试获取远程连接用户的地址时遇到了错误。

while(run == 1) {
    struct sockaddr_in client_addr;
    char message[1024];
    int len = recvfrom(sockfd, message, 1024, 0, (struct sockaddr*)&client_addr, sizeof client_addr);

    printf("Received request from: %s#%d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
}

它总是返回远程地址:0.0.0.0#0

【问题讨论】:

  • 最后一个参数应该是一个指针。它是否还返回 -1 并将 errno 设置为 EFAULT,是否有任何机会?
  • 它返回-1,错误信息是:Bad address
  • 该代码甚至不应该编译。您是否在许可模式下编译?你不应该!
  • 它返回-1,错误信息是:Bad address 这就是为什么你总是检查返回码。

标签: c sockets unix udp datagram


【解决方案1】:

如果您阅读recvfrom 的文档,您会看到最后一个参数是一个指向一个socklen_t 的指针,该socklen_t 保存着地址的大小。

应该是这样的:

socklen_t client_addr_len = sizeof client_addr;
int len = recvfrom(....., (struct sockaddr*)&client_addr, &client_addr_len);

在调用recvfrom 之后,client_addr_len 将保存实际地址长度(理论上,如果不是 AF_INET 地址,它可能小于缓冲区)。

【讨论】:

    【解决方案2】:

    recvfrom() 调用的最后一个参数不正确。它应该是一个socklen_t * 类型的指针,指向最初存储地址大小的位置。该函数修改存储在那里的值以反映地址结构的实际大小,就像它编写的那样,或者如果初始大小足够大,它编写它。您改为传递实际大小,该大小必须隐式转换为指针。你的编译器应该警告你。

    鉴于程序没有崩溃,recvfrom() 必须成功地从转换后的整数指向的地址读取一个值,并成功地在那里写入一个值。很可能,它正在读取值0

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多