我有一个
struct addrinfo
,这是为了建立联系而传递的:
struct addrinfo* address;
...
int fd = socket(address->ai_family, address->ai_socktype, address->ai_protocol);
...
int res = ::connect(fd, address->ai_addr, address->ai_addrlen);
如果连接成功,我想记录目标IP地址。
如何从这个结构中提取 IP 地址(作为要记录的字符串)?谷歌搜索结果只给出
getaddrinfo()
的结果。
您可以使用
inet_ntop
将 IPv4 或 IPv6 地址转换为字符串。
char addr[INET6_ADDRSTRLEN];
if (inet_ntop(address->ai_family, address->ai_addr, addr, address->ai_addrlen)) {
printf("address=%s\n", addr);
} else {
perror("invalid address");
}
你可以使用 [Man7]: INET_NTOP(3):
Cast ai_addr成员到sockaddr_in(或sockaddr_in6)结构
在(上)结构的sin_addr(sin6_addr)成员上调用inet_ntop
code00.c:
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
int main()
{
struct addrinfo *pai = NULL;
int err = getaddrinfo("www.example.com", NULL, NULL, &pai);
if (err != 0) {
fprintf(stderr, "error in getaddrinfo: %s\n", gai_strerror(err));
return -1;
}
if (pai->ai_family == AF_INET) {
struct sockaddr_in *psai = (struct sockaddr_in*)pai->ai_addr;
char ip[INET_ADDRSTRLEN];
if (inet_ntop(pai->ai_family, &(psai->sin_addr), ip, INET_ADDRSTRLEN) != NULL) {
printf("IP: %s\n", ip);
}
} else if (pai->ai_family == AF_INET6) {
struct sockaddr_in6 *psai = (struct sockaddr_in6*)pai->ai_addr;
char ip[INET6_ADDRSTRLEN];
if (inet_ntop(pai->ai_family, &(psai->sin6_addr), ip, INET6_ADDRSTRLEN) != NULL) {
printf("IP: %s\n", ip);
}
} else {
printf("Don't know how to convert family %d addresses\n", pai->ai_family);
}
freeaddrinfo(pai);
printf("\nDone.\n\n");
return 0;
}
输出:
[cfati@cfati-5510-0:/mnt/e/Work/Dev/StackExchange/StackOverflow/q075843180]> ~/sopr.sh ### Set shorter prompt to better fit when pasted in StackOverflow (or other) pages ### [064bit prompt]> gcc -o main00.exe main00.c [064bit prompt]> ./main00.exe IP: 93.184.216.34 Done.
要从 C 中的
struct addrinfo
中提取 IP 地址(作为字符串),您可以使用 inet_ntop()
函数。这是一个如何使用它的例子:
#include <arpa/inet.h>
struct addrinfo* address;
// assume that address is initialized and used to create a socket
char ipstr[INET6_ADDRSTRLEN];
void* addr;
if (address->ai_family == AF_INET) { // IPv4
struct sockaddr_in *ipv4 = (struct sockaddr_in *)address->ai_addr;
addr = &(ipv4->sin_addr);
} else { // IPv6
struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)address->ai_addr;
addr = &(ipv6->sin6_addr);
}
// convert the IP address to a string
inet_ntop(address->ai_family, addr, ipstr, sizeof ipstr);
// log the IP address
printf("The destination IP address is: %s\n", ipstr);
此代码使用 inet_ntop() 函数将 struct addrinfo 的 ai_addr 字段中的二进制 IP 地址转换为字符串表示形式(IPv4 或 IPv6,具体取决于 ai_family 字段)。结果字符串存储在 ipstr 数组中,可以根据需要记录或打印。