C++ 如何从'sockaddr_storage'实例检索IP和端口?
如何使用C++ 如何从'sockaddr_storage'实例检索IP和端口?,c++,c,sockets,networking,winsock,C++,C,Sockets,Networking,Winsock,如何使用getnameinfo()()从sockaddr\u存储实例检索IP和端口 当我使用inet\u ntop时,它工作正常,但当我用getnameinfo函数替换它时,Windows返回了一个错误: 代码10047:使用了与请求的协议不兼容的地址 我查看了您的问题,并能够重现您的错误 可复制示例: #define WIN32_LEAN_AND_MEAN #define _WINSOCK_DEPRECATED_NO_WARNINGS #include <cstdint> #in
getnameinfo()
()从sockaddr\u存储
实例检索IP和端口
当我使用inet\u ntop
时,它工作正常,但当我用getnameinfo
函数替换它时,Windows返回了一个错误:
代码10047:使用了与请求的协议不兼容的地址
我查看了您的问题,并能够重现您的错误 可复制示例:
#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, SOCK_DGRAM, 0);
#endif
sockaddr_storage address;
int length = sizeof(sockaddr_storage);
char buffer[1];
recvfrom(fd, buffer, sizeof buffer, 0, (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, ip, 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, ip, INET_ADDRSTRLEN);
uint16_t port_ = ntohs(sa->sin_port);
#endif
}
一旦您这样做,您就不会再看到错误10047,您应该能够打印ip和端口缓冲区的内容并查看相应的信息
参考资料:
#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, SOCK_DGRAM, 0);
#endif
sockaddr_storage address;
int length = sizeof(sockaddr_storage);
char buffer[1];
recvfrom(fd, buffer, sizeof buffer, 0, (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, ip, 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, ip, INET_ADDRSTRLEN);
uint16_t port_ = ntohs(sa->sin_port);
#endif
}
sockaddr_storage address;
address.ss_family = AF_INET;