gethostname和getaddrinfo
时间: 2024-04-29 22:23:51 浏览: 18
gethostname函数是获取当前主机名的函数,它的原型如下:
```
int gethostname(char *name, size_t len);
```
其中参数name是一个指向用于存储主机名的缓冲区的指针,len是该缓冲区的大小。如果函数调用成功,它将主机名存储在缓冲区中,并返回0;如果失败,则返回-1,并设置errno变量。
getaddrinfo函数是获取一个主机名或服务名对应的IP地址和端口号的函数,它的原型如下:
```
int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res);
```
其中node参数是主机名或IP地址,service参数是服务名或端口号,hints参数是一个addrinfo结构体指针,用于指定一些选项和限制条件,res参数是一个指向addrinfo结构体链表的指针,用于存储获取到的结果。
如果函数调用成功,它将返回0,并将获取到的结果存储在res指针所指向的链表中;如果失败,则返回一个非零错误码,并设置errno变量。在使用完结果后,应该调用freeaddrinfo函数释放所分配的内存。
相关问题
getaddrinfo();
getaddrinfo()函数是一个用于解析主机名和服务名的函数。它可以将主机名和服务名转换为一个或多个网络地址结构。该函数的原型如下:
```c
int getaddrinfo(const char *hostname, const char *service, const struct addrinfo *hints, struct addrinfo **result);
```
根据引用和引用的内容,我们可以了解到getaddrinfo()函数在实际使用中的几种常用参数设置:
1. 服务器端调用getaddrinfo()之前,通常将ai_flags设置为AI_PASSIVE,用于bind。主机名nodename通常设置为NULL,这样会返回通配地址[::]。
2. 客户端调用getaddrinfo()时,一般不设置ai_flags为AI_PASSIVE,但是主机名nodename和服务名servname(端口)应该不为空。
3. 即使不设置ai_flags为AI_PASSIVE,取出的地址也可以被bind。很多程序中ai_flags直接设置为0,即3个标志位都不设置,这种情况下只要hostname和servname设置正确,就可以正确bind。
综上所述,getaddrinfo()函数可以根据主机名和服务名解析出一个或多个网络地址结构,并根据不同的使用场景进行相应的参数设置。
getaddrinfo函数使用
getaddrinfo函数是用于将主机名和服务名转化为套接字地址的函数。该函数可以根据传入的参数获取与主机名和服务名相匹配的地址信息,返回一个addrinfo结构体链表,每个结构体包含了主机名、服务名、协议、IP地址等信息。
下面是该函数的使用方法:
```c
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
int getaddrinfo(const char *node, const char *service,
const struct addrinfo *hints, struct addrinfo **res);
```
其中,node表示主机名或IP地址,service表示服务名或端口号,hints表示筛选条件,res表示返回的addrinfo结构体链表。
示例代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <arpa/inet.h>
int main(int argc, char *argv[]) {
struct addrinfo hints, *res;
int status;
memset(&hints, 0, sizeof hints); // 清空hints结构体
hints.ai_family = AF_UNSPEC; // 既可以是IPv4也可以是IPv6
hints.ai_socktype = SOCK_STREAM; // 流式套接字
if (argc != 2) {
fprintf(stderr, "usage: %s hostname\n", argv[0]);
return 1;
}
if ((status = getaddrinfo(argv[1], NULL, &hints, &res)) != 0) {
fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
return 2;
}
printf("IP addresses for %s:\n\n", argv[1]);
struct addrinfo *p;
char ipstr[INET6_ADDRSTRLEN];
for (p = res; p != NULL; p = p->ai_next) {
void *addr;
char *ipver;
if (p->ai_family == AF_INET) { // IPv4
struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
addr = &(ipv4->sin_addr);
ipver = "IPv4";
} else { // IPv6
struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;
addr = &(ipv6->sin6_addr);
ipver = "IPv6";
}
inet_ntop(p->ai_family, addr, ipstr, sizeof ipstr);
printf("%s: %s\n", ipver, ipstr);
}
freeaddrinfo(res); // 释放addrinfo链表
return 0;
}
```
该程序接受一个主机名作为命令行参数,然后使用getaddrinfo函数获取该主机名对应的IP地址信息,并打印出所有的IP地址。其中,将hints结构体的ai_family成员设置为AF_UNSPEC表示既可以是IPv4也可以是IPv6,hints结构体的ai_socktype成员设置为SOCK_STREAM表示流式套接字。在for循环中,判断addrinfo结构体的ai_family成员,来确定IPv4或IPv6的地址信息,并使用inet_ntop函数将网络字节序转换为主机字节序的IP地址,并打印出来。最后,记得释放addrinfo链表。