如何从`sockaddr_storage`实例中检索IP和端口?

如何解决如何从`sockaddr_storage`实例中检索IP和端口?

如何使用sockaddr_storageref)从getnameinfo()实例检索IP和端口?

当我使用inet_ntop时,它的工作正常,但是当我将其替换为getnameinfo函数时,Windows返回了一个错误:

代码10047:使用了与请求的协议不兼容的地址。

#ifdef USE_IPV6
int fd = socket(AF_INET6,SOCK_DGRAM,0);
#else
int fd = socket(AF_INET,0);
#endif

sockaddr_storage address;
int length = sizeof address;

char buffer[1];
recvfrom(fd,buffer,sizeof buffer,(struct sockaddr *) &address,&length);

// Error
char ip[NI_MAXHOST];
char port[NI_MAXSERV];
int rc = getnameinfo((struct sockaddr *) &address,length,ip,sizeof ip,port,sizeof port,NI_NUMERICHOST | NI_NUMERICSERV);
if (rc) WSAGetLastError(); // Error Code = 10047

// Works
#ifdef USE_IPV6
struct sockaddr_in6 *sa = (struct sockaddr_in6 *) &address;
inet_ntop(AF_INET6,&sa->sin6_addr,INET6_ADDRSTRLEN);
uint16_t port_ = ntohs(sa->sin6_port);
#else
struct sockaddr_in *sa = (struct sockaddr_in *) &address;
inet_ntop(AF_INET,&sa->sin_addr,INET_ADDRSTRLEN);
uint16_t port_ = ntohs(sa->sin_port);
#endif

解决方法

我查看了您的问题,并能够重现您遇到的错误。

可复制的示例:

#define WIN32_LEAN_AND_MEAN
#define _WINSOCK_DEPRECATED_NO_WARNINGS

#include <cstdint>
#include <cstdlib>
#include <iostream>
#include <windows.h>
#include <WinSock2.h>
#include <WS2tcpip.h>

int main(int,char **) {

  WORD wVersionRequested = MAKEWORD(2,2);
  WSADATA wsaData;
  WSAStartup(wVersionRequested,&wsaData);

#ifdef USE_IPV6
  int fd = socket(AF_INET6,SOCK_DGRAM,0);
#else
  SOCKET fd = socket(AF_INET,0);
#endif

  sockaddr_storage address;
  int length = sizeof(sockaddr_storage);

  char buffer[1];
  recvfrom(fd,buffer,sizeof buffer,(struct sockaddr*)&address,&length);

  // Error
  char ip[NI_MAXHOST];
  char port[NI_MAXSERV];
  int rc = getnameinfo((struct sockaddr*)&address,length,ip,sizeof(ip),port,sizeof(port),NI_NUMERICHOST | NI_NUMERICSERV);
  if (rc)
    WSAGetLastError(); // Error Code = 10047

  std::cout << "IP: " << ip << std::endl;
  std::cout << "Port: " << port << std::endl;

// Works
#ifdef USE_IPV6
  struct sockaddr_in6* sa = (struct sockaddr_in6*)&address;
  inet_ntop(AF_INET6,&sa->sin6_addr,INET6_ADDRSTRLEN);
  uint16_t port_ = ntohs(sa->sin6_port);
#else
  struct sockaddr_in* sa = (struct sockaddr_in*)&address;
  inet_ntop(AF_INET,&sa->sin_addr,INET_ADDRSTRLEN);
  uint16_t port_ = ntohs(sa->sin_port);
#endif
}

问题在于您没有设置ss_family结构的sockaddr_storage字段。

要解决此问题,您需要在ss_family中指定sockaddr_storage值,如下所示:

sockaddr_storage address;
address.ss_family = AF_INET;

执行完此操作后,您将不再看到错误10047,并且应该能够打印ip和port缓冲区的内容并查看相应的信息。

参考:

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?