17 Eylül 2015 Perşembe

Socket Veri Yapıları

Giriş
Soket tiplerine göre API'de kullanılan veri yapıları değişkenlik gösteriyor.

Genel
sockaddr
Socket metodlarını çoklamamak için tüm struct'ların ortak atası gibi bir yapı düşünülmüş. Yapı şöyle tanımlı. sa_data'nın 14 bit olması tamamen tesadüf. Başka bir sayı da olabilirdi çünkü bir önemi yok.
struct sockaddr {
    sa_family_t sa_family;
    char        sa_data[14];
}
İşletim sistemi açısından önemli olan alan 2 byte uzunluğundaki sa_family alanı. sockaddr_in, sockaddr_in6 ve sockaddr_un veri yapılarının hepsinin ilk elemanı "family" yani soket çeşidini gösteren alan ile başlar.

Bu yapı ile sendto, bind vs. gibi metodların hepsinde paramtre olarak geçiliyor. Örneğin bind metodunun imzası şöyle.
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

IPV4
sockaddr_in
Bu yapı IPv4 ile kullanılan en temel yapı. İçi şöyle
struct sockaddr_in {
    short            sin_family;   // e.g. AF_INET, AF_INET6
    unsigned short   sin_port;     // e.g. htons(3490)
    struct in_addr   sin_addr;     // see struct in_addr, below
    char             sin_zero[8];  // zero this if you want to
}; 
Linux'ta şöyle tanımlı. Yukarıdaki yapı ile aynı kapıya çıkıyor.
struct sockaddr_in {
    sa_family_t    sin_family; /* address family: AF_INET */
    in_port_t      sin_port;   /* port in network byte order */
    struct in_addr sin_addr;   /* internet address */
};

/* Internet address. */
struct in_addr {
    uint32_t       s_addr;     /* address in network byte order */
};

Windows dünyasında bu yapı büyük harflerler yazılmış. Yani SOCKADDR_IN şeklinde.

sockaddr_in bind(), connect() ,sento() metodlarına parametere olarak geçilir.
accept(), recvfrom(), getsockname(), getpeername() metodları ise sockaddr_in parametresini doldurarak döndürürler.

Bu yapı şöyle doldurulur. Beni en gıcık eden şey sin_addr.s_addr alanını bir türlü hatırlayamamam.

struct sockaddr_in clientService;
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = inet_addr("10.0.0.1");                            
clientService.sin_port = htons(80); 
in_addr
Bu veri yapısı IPv4 adresini binary olarak saklamaya yarar

IPV6
sockaddr_in6
Bu yapı IPv6 ile kullanılan en temel yapı. İçi şöyle
struct sockaddr_in6 {
    u_int16_t       sin6_family;   // address family, AF_INET6
    u_int16_t       sin6_port;     // port number, Network Byte Order
    u_int32_t       sin6_flowinfo; // IPv6 flow information
    struct in6_addr sin6_addr;     // IPv6 address
    u_int32_t       sin6_scope_id; // Scope ID
};

struct in6_addr {
    unsigned char   s6_addr[16];   // IPv6 address
};

Ethernet
sockaddr_ll
Bu veri yapısı Linux'ta ethernet seviyesinde veri göndermek için kullanılır.

Unix
sockaddr_un
Yapı şöyle
struct sockaddr_un {
    sa_family_t sun_family;               /* AF_UNIX */
    char        sun_path[108];            /* pathname */
};





Hiç yorum yok:

Yorum Gönder