IP Adresleri ve Bunlarla Uğraşma Yöntemleri
Önceki struct'lar ve Veri İle Uğraşmak Sonraki
IP Adresleri ve Bunlarla Uğraşma Yöntemleri
Şanslısınız çünkü IP adresleri ile uğraşmanızı sağlayacak bir grup işlev vardır. Yani elle hesap kitap yapıp sonra da bunu bir long içine << işleci ile tıkıştırmanıza gerek yok.
Önce örneğin elinizde bir struct sockaddr_in ina değişkeni ve bir de 10.12.110.57 şeklinde bir IP adresi olduğunu var sayalım. Bu adresi bu değişken içine yerleştirmek istiyorsunuz. Kullanmanız gereken işlev: inet_addr(). Bu işlev bir IP adresini yukarıdaki gibi sayılardan ve noktalardan oluşan bir biçemden alıp unsigned long türünde bir sayıya çevirir. Bu tür bir atama şu şekilde yapılabilir:
ina.sin_addr.s_addr = inet_addr("10.12.110.57"); 
Şuna dikkat edin: inet_addr() zaten döndürdüğü değeri Ağ Bayt Sıralamasına göre dizilmiş olarak döndürür yani htonl() işlevini burada çağırmanıza gerek yok. Harika!
Yukarıdaki kod parçası pek sağlam sayılmaz çünkü hiç hata denetimi yok. Gördüğünüz gibi inet_addr() hatalı bir durumla karşılaşınca -1 değerini döndürür. İkili sayı sistemini hatırladınız mı? (unsigned)-1 tam da şu IP adresine karşılık gelir: 255.255.255.255! Bu da yayın adresidir! Aman dikkat. Hata kontrolünü düzgün bir şekilde yapmayı sakın ihmal etmeyin.
Aslında inet_addr() yerine kullanabileceğiniz daha güzel bir işlev var: inet_aton() ("aton"u, "ascii to network" olarak okuyun):
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int inet_aton(const char *cp, struct in_addr *inp); 
Bir örnek vermek gerekirse: bu işlev struct sockaddr_in yapısını paketlerken (ilerledikçe bu örnek size daha da anlamlı gelecek bind() ve connect() kısımlarına kadar sabredin.)
struct sockaddr_in my_addr;

my_addr.sin_family = AF_INET;         // konak bayt sıralaması
my_addr.sin_port = htons(MYPORT);     // short, ağ bayt sıralaması
inet_aton("10.12.110.57", &(my_addr.sin_addr));
memset(&(my_addr.sin_zero), '\0', 8); // geriye kalanı sıfırla 
inet_aton(), diğer tüm soket-bağlantılı işlevlerden farklı olarak, sorun çıkmazsa sıfırdan farklı bir değer, sorun çıkarsa da sıfır değerini döndürür. Ve döndürülen adres inp içinde yer alır.
Maalesef her platform inet_aton() işlevini kullanmamaktadır. Bu yüzden her ne kadar bu işlevi tercih etsek de daha yaygın olması itibariyle örneklerde inet_addr() kullanılacaktır.
Artık IP adreslerini ikilik sisteme kolayca dönüştürebileceğinize göre bunun tersini yapmaya ne dersiniz? Yani mesela elinizde zaten bir struct in_addr yapısı varsa ve siz bunu alışık olduğunuz sayılı noktalı IP adresi biçeminde basmak istiyorsanız? Bu durumda kullanacağımız işlev: inet_ntoa() ("ntoa"yı "network to ascii" olarak okuyun). Şu şekilde işinizi görür:
printf("%s", inet_ntoa(ina.sin_addr)); 
Bu IP adresini basacaktır. Dikkat edin: inet_ntoa() argüman olarak struct in_addr alır long almaz. Bir diğer önemli nokta da: Bu işlev bir char'a işaret eden bir gösterge döndürür. Söz konusu gösterge inet_ntoa() içinde statik olarak depolanan bir karakter dizisine işaret eder ve inet_ntoa() işlevini her çağırışınızda son işlem görmüş olan IP adresinin üzerine yazılır. Örneğin:
char *a1, *a2;
.
.
a1 = inet_ntoa(ina1.sin_addr);  // burada 192.168.4.14 var
a2 = inet_ntoa(ina2.sin_addr);  // burada 10.12.110.57 var
printf("1. adres: %s\n",a1);
printf("2. adres: %s\n",a2); 
şunu basar:
1. adres: 10.12.110.57
2. adres: 10.12.110.57 
Eğer birden fazla adresle iş yapıyorsanız ve bunları yukarıda olduğu gibi kaybetmek istemiyorsanız o zaman strcpy() gibi bir işlev kullanarak uygun bir yere kopyalamayı sakın ihmal etmeyin.
Bu konu ile söyleyeceklerim şimdilik bu kadar. Daha sonra "whitehouse.gov" gibi bir karakter dizisini hangi yöntemlerle karşılık gelen IP adresine çevirebileceğinizi göstereceğim (bkz. DNS -- Sen "whitehouse.gov" de, ben de "198.137.240.92" diyeyim).
Önceki Üst Ana Başlık Sonraki
Veri Türlerini Dönüştür! Başlangıç Sistem Çağrıları veya Felaketleri
Bir Linux Kitaplığı Sayfası