DNS -- Sen "whitehouse.gov" de, ben de "198.137.240.92" diyeyim
Önceki Sistem Çağrıları veya Felaketleri Sonraki
DNS -- Sen "whitehouse.gov" de, ben de "198.137.240.92" diyeyim
Eğer DNS'in ne olduğunu bilmiyorsanız söyleyeyim: "Domain Name System" yani "Alan Adı Sistemi" demek. Kısaca siz ona kolayca hatırlayabildiğiniz adresi verirsiniz o da size buna karşılık gelen IP adresini verir (ki siz de bu bilgiyi bind(), connect(), sendto() ve diğer işlevleri çağırırken kullanabilesiniz). Böylece biri:
$ telnet whitehouse.gov
komutunu girdiğinde telnet yazılımı connect() işlevine verilmesi gereken "198.137.240.92" bilgisine erişebilir.
Peki bu nasıl çalışır? Bunun için gethostbyname() işlevini kullanacaksınız:
#include <netdb.h>

struct hostent *gethostbyname(const char *name); 
Gördüğünüz gibi bu işlev struct hostent türünde bir gösterge döndürür. Söz konusu türün ayrıntılı yapısı da şöyledir:
struct hostent {
    char    *h_name;
    char    **h_aliases;
    int     h_addrtype;
    int     h_length;
    char    **h_addr_list;
};
#define h_addr h_addr_list[0] 
Bu karmaşık değişkenin içindeki alanların açıklamalarına gelince:
  • h_name -- Konağın resmi ismi.
  • h_aliases -- Söz konusu konağın alternatif isimleri, NULL ile sonlandırılmış karakter dizileri şeklinde.
  • h_addrtype -- Dönen adresin türü, genellikle AF_INET değerini alır.
  • h_length -- Byte cinsinden adresin uzunluğu.
  • h_addr_list -- Konağın ağ adresinin sıfır sonlandılmalı dizisi. Konak adresleri ağ bayt sıralamasına sahiptir.
  • h_addr -- h_addr_list listesindeki ilk adres.
gethostbyname() çalıştıktan sonra içini doldurduğu struct hostent türünden bir gösterge döndürür. Eğer hata oluşursa NULL döndürür. (Fakat errno değişkeni ile ilgili herhangi bir işlem yapmaz -- bunun yerine h_errno değişkeni kullanılır. Ayrıntılı bilgi için aşağıdaki herror() işlevine bakın.)
Peki tüm bu bilgileri nasıl kullanacağız? Bazen okuyucuya bilgi yığınını verip onu bununla başbaşa bırakmak yeterli olmaz (bilgisayar belgelerini okuyanlar ne demek istediğimi anlıyorlardır). Bu işlevi kullanmak düşündüğünüzden daha kolaydır.
/*
** getip.c -- konak isminden IP adresini elde edilmesi
*/

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main(int argc, char *argv[])
{
    struct hostent *h;

    if (argc != 2) {  // komut satırında hata denetimi
        fprintf(stderr,"usage: getip konak_ismi\n");
        exit(1);
    }

    if ((h=gethostbyname(argv[1])) == NULL) {  // konak bilgilerini al
        herror("gethostbyname");
        exit(1);
    }

    printf("Konak ismi: %s\n", h->h_name);
    printf(" IP Adresi: %s\n", inet_ntoa(*((struct in_addr *)h->h_addr)));

   return 0;
} 
gethostbyname() söz konusu olduğunda perror() işlevini hata mesajını basmak için kullanamazsınız (çünkü errno gerekli değeri almaz). Bunun yerine herror() işlevini kullanmalısınız.
Açıklama basit: Doğrudan ilgilendiğiniz makinanın Internet adresini verirsiniz ("whitehouse.gov") ve gethostbyname() işlevi de çalışıp işini bitirdikten sonra size struct hostent türünde bir değişken döndürür.
Buradaki tek gariplik şudur: IP adresini basarken kullanmanız gereken h->h_addr, char* türündedir ama inet_ntoa() işlevi struct in_addr türünde bir değişken isteme konusunda ısrarcı olduğu için önce h->h_addr değiğkenini struct in_addr* türüne çevirdim ve ardından veriye ulaştım.
Önceki Üst Ana Başlık Sonraki
gethostname() -- Ben kimim? Başlangıç İstemci-Sunucu Mimarisi
Bir Linux Kitaplığı Sayfası