Giriş
Linux'ta şu satırları dahil ederiz.
Kullanım
Örnek
Şöyle yaparız. Burada belirtilen bir adres için sorgulama yapılıyor.
Sonuç Listesini Kullanmak - ai_family + ai_socktype + ai_protocol
Elde edilen sonuç socket açmak için kullanılabilir.
Örnek
Şöyle yaparız
Elde edilen sonuç sunucu socket için kullanılabilir.
Örnek
Şöyle yaparız.
Şöyle yaparız. Belirtilen IP adresi veya sunucuya ait IP numaraları bulunuyor ve ilki için isim sorgulaması yapılıyor.
ai_addr alanı IPv4 veya IPv6 adresi içerir. bind için kullanılabilir.
Linux'ta şu satırları dahil ederiz.
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
İmzası şöyleint getaddrinfo(const char *node,
const char *service,
const struct addrinfo *hints,
struct addrinfo **res);
Verilen metini (isim veya IP adresi) binary formata çevirir. Gerekirse DNS sunucuna istekte bulunur. Döndürülen result listesi freeaddrinfo() ile silinmelidir, yoksa memory leak olur.Kullanım
Örnek
Şöyle yaparız. Burada belirtilen bir adres için sorgulama yapılıyor.
struct addrinfo *ai;
struct addrinfo hints = ...; //1 Alanları doldur
int res = getaddrinfo(..., NULL, &hints, &ai); //2 Çağrıyı yap
if (res) { //Sonucu kontrol et
fprintf(stderr, "%s: %s\n", argv[1], gai_strerror(res));
return 1;
}
...
freeaddrinfo(ai); //Belleği sil
Örnek
Şöyle kullanırız.#define PORT "32001"
struct addrinfo hints, *res;
// Get the address info
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
if (getaddrinfo(NULL, PORT, &hints, &res) != 0) {
perror("getaddrinfo");
return 1;
}
İşimiz bitince nesne şöyle silinir.freeaddrinfo(res);
Hata Varsa
Şöyle yaparız.
Aramak istediğimiz IP adresini veya sunucu ismini belirtir. Açıklaması şöyle.
Genellikle null verilir. Açıklaması şöyle. Yani string şeklinde "http" veya string şeklinde "80" gibi bir sayı olmalı.
3. hints parametresi
7 tane alan vardır. Bunlardan genellikle ai_family ve ai_socktype alanları doldurulur.
3.1. hints.ai_family Alanı
3.2 hints.ai_socktype Alanı
- Stream ailesine ait değerler şunlar. IPPROTO_TCP, IPPROTO_SCTP.
- Datagram ailesine ait değerler şunlar. IPPROTO_UDP, IPPROTO_UDPLITE.
- Ayrıca SOCK_SEQPACKET ve SOCK_DCCP aileleri de var.
Örnek
TCP için şöyle yaparız.
UDP için şöyle yaparız.
3.3 hints.ai_flags Alan
Şöyle yaparız.
Sonuçları Dolaşmak
Şöyle yaparız.
Sadece IPv6 adreslerini kullanmak için şöyle yaparız.Şöyle yaparız.
int error = getaddrinfo(...,...,...,...);
if (error) {
printf("Error %d: %s\n\n", error, gai_strerror(error));
return;
}
1. node ParametresiAramak istediğimiz IP adresini veya sunucu ismini belirtir. Açıklaması şöyle.
node specifies either a numerical network address, or a network hostname, whose network addresses are looked up and resolved.2. service Parametresi
Genellikle null verilir. Açıklaması şöyle. Yani string şeklinde "http" veya string şeklinde "80" gibi bir sayı olmalı.
service sets the port in each returned address structure. If this argument is a service name (see services(5)), it is translated to the corresponding port number. This argument can also be specified as a decimal number, which is simply converted to binary. If service is NULL, then the port number of the returned socket addresses will be left uninitialized.
3. hints parametresi
7 tane alan vardır. Bunlardan genellikle ai_family ve ai_socktype alanları doldurulur.
3.1. hints.ai_family Alanı
3.2 hints.ai_socktype Alanı
- Stream ailesine ait değerler şunlar. IPPROTO_TCP, IPPROTO_SCTP.
- Datagram ailesine ait değerler şunlar. IPPROTO_UDP, IPPROTO_UDPLITE.
- Ayrıca SOCK_SEQPACKET ve SOCK_DCCP aileleri de var.
Örnek
TCP için şöyle yaparız.
struct addrinfo hints;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;hints.ai_protocol =
IPPROTO_TCP;
ÖrnekUDP için şöyle yaparız.
struct addrinfo hints;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_DGRAM;
3.3 hints.ai_flags Alan
Şöyle yaparız.
struct addrinfo hints = {
.ai_flags = AI_NUMERICHOST,
.ai_family = AF_UNSPEC,
};
Sonuçları Dolaşmak
Şöyle yaparız.
struct addrinfo hints, *res, *p;
...
int error = getaddrinfo(...,...,..., &res);
...
for (p = res; p != NULL; p = p->ai_next) {
...
}
Süzerek Dolaşmakconst std::string hostname = ...; const std::string port = ...;
struct addrinfo hints;
struct addrinfo* res {nullptr};
struct addrinfo* ptr {nullptr};
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
int rv;
if((rv = getaddrinfo(hostname.c_str(), port.c_str(), &hints, &res)) != 0) {
return -1;
}
// Try to get the first available client connection.
for(ptr = res; ptr != nullptr; ptr = ptr->ai_next) {
// Ignore undefined ip type.
if(ptr->ai_family != AF_INET && ptr->ai_family != AF_INET6) {
continue;
}
...
}
freeaddrinfo(res);
Elde edilen sonuç socket açmak için kullanılabilir.
Örnek
Şöyle yaparız
int sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
Sonuç Listesi Kullanmak - ai_addr + ai_addrlenElde edilen sonuç sunucu socket için kullanılabilir.
Örnek
Şöyle yaparız.
/* Bind to the address */
if (bind(sock, res->ai_addr, res->ai_addrlen) == -1) {
...error...
}
ÖrnekŞöyle yaparız. Belirtilen IP adresi veya sunucuya ait IP numaraları bulunuyor ve ilki için isim sorgulaması yapılıyor.
struct addrinfo *ai;
struct addrinfo hints = ...
int res = getaddrinfo(argv[1], NULL, &hints, &ai);
if (res) {
fprintf(stderr, "%s: %s\n", argv[1], gai_strerror(res));
return 1;
}
char node[NI_MAXHOST];
res = getnameinfo(ai->ai_addr, ai->ai_addrlen, node, sizeof node, NULL, 0, NI_NAMEREQD);
freeaddrinfo(ai);
Sonuç Listesi Kullanmak - ai_addr alanıai_addr alanı IPv4 veya IPv6 adresi içerir. bind için kullanılabilir.
bind(sock, res->ai_addr, res->ai_addrlen)
İstemci socket olarak connect için kullanılabilir.if(connect(sock, (struct sockaddr*)res->ai_addr, ptr->ai_addrlen) < 0) {
...
}
Eğer ai_family AF_INET6 ise IPv6 adresini şöyle alabiliriz.unsigned char buf[16];
struct sockaddr_in6 *in6 = (struct sockaddr_in6*)res->ai_addr;
memcpy(buf, in6->sin6_addr.s6_addr, 16);
IPv6 byte'larını şöyle görebiliriz.for (int i = 0; i < 16; i++) {
printf("%02X", buf[i]);
if (i < 15) putchar(':');
}
ya da string olarak görebiliriz.char str[64];
printf("%s\n", inet_ntop(AF_INET6, buf, str, sizeof buf));
Hiç yorum yok:
Yorum Gönder