2015-09-17 7 views
5
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); 

एडीआर तर्क के लिए पारित वास्तविक संरचना पता परिवार पर निर्भर करेगी। sockaddr संरचना की तरह कुछ के रूप में परिभाषित किया गया है:सॉकडर में sa_data फ़ील्ड का उद्देश्य क्या है?

struct sockaddr { 
    sa_family_t sa_family; 
    char  sa_data[14]; 
} 
एक IPv4 एड्रेस (AF_INET) के लिए

तो, वास्तविक struct कि पारित हो जाएगा यह है:

/* Source http://linux.die.net/man/7/ip */ 

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 */ 
}; 

बाँध कोड sockaddr.sa_family मूल्य पढ़ा करता है और उसके द्वारा प्राप्त मूल्य के आधार पर, sockaddr संरचना को उपयुक्त संरचना में sockaddr_in पर डाला जाएगा?

sa_data क्यों 14 वर्णों पर सेट है? अगर मैं सही समझता हूं, तो sa_data फ़ील्ड केवल एक ऐसा क्षेत्र है जिसमें परिवार के सभी प्रकार के पते को फिट करने के लिए पर्याप्त मेमोरी स्पेस होगा? संभवतः मूल डिजाइनरों ने अनुमान लगाया कि 14 वर्ण सभी भविष्य के प्रकारों के अनुरूप पर्याप्त होंगे।

+0

https://en.wikipedia.org/wiki/Type_punning – user3386109

उत्तर

5

glibc manual के अनुसार:

sa_data की लंबाई 14 अनिवार्य रूप से मनमाना है।

और FreeBSD developers handbook निम्नलिखित का उल्लेख है:

कृपया अस्पष्टता जिसके साथ sa_data क्षेत्र घोषित किया जाता है, ध्यान दें सिर्फ 14 बाइट्स की एक सरणी के रूप में, टिप्पणी इशारा के साथ वहाँ की तुलना में अधिक हो सकता है उनमें से 14।

यह अस्पष्टता काफी जानबूझकर है। सॉकेट एक बहुत ही शक्तिशाली इंटरफ़ेस है। जबकि ज्यादातर लोग शायद से अधिक इंटरनेट इंटरफ़ेस के रूप में नहीं सोचते हैं- और अधिकांश एप्लिकेशन शायद के लिए इसका उपयोग करते हैं-सॉकेट का उपयोग किसी भी तरह के इंटरप्रोसेस संचारों के लिए किया जा सकता है, जिनमें से इंटरनेट (या, अधिक सटीक , आईपी) केवल एक है।

हाँ, sa_family क्षेत्र कैसे struct पारित कर दिया (जो बाध्य करने के लिए एक कॉल में struct sockaddr* को डाला जाता है) के इलाज के लिए पहचान करने के लिए प्रयोग किया जाता है। FreeBSD developers handbook में यह कैसे काम करता है इसके बारे में आप और अधिक पढ़ सकते हैं।

और वास्तव में वहाँ "बहुरूपी" (उप) sockaddr के प्रकार, जिसमें sa_data उदाहरण के लिए, 16 से अधिक बाइट का है कर रहे हैं:

struct sockaddr_un { 
    sa_family_t sun_family;    /* AF_UNIX */ 
    char  sun_path[108];   /* pathname */ 
}; 
3

sockaddr struct एक टैग किए गए संघ के रूप में प्रयोग किया जाता है। sa_family फ़ील्ड को पढ़कर इसे उचित रूप की संरचना में डाला जा सकता है।

14 बाइट मनमाने ढंग से हैं। आईपीवी 4 पते रखने के लिए काफी बड़ा है, लेकिन आईपीवी 6 पते रखने के लिए पर्याप्त नहीं है। sockaddr_storage संरचना भी है जो दोनों के लिए काफी बड़ी है। SOCKADDR_STORAGE पर माइक्रोसॉफ्ट डॉक्स पढ़ना, यह 128 बाइट्स में आता है, आईपीवी 6 के लिए आवश्यक से बहुत बड़ा है। कुछ लिनक्स हेडर की जांच कर रहा है, ऐसा लगता है कि कम से कम वहां भी बड़ा है।

संदर्भ के लिए, आईपीवी 6 struct है:

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 
}; 

आप देख सकते हैं, 16 बाइट s6_addr क्षेत्र अपने आप पर 14 बाइट sa_data क्षेत्र से पहले से ही बड़ा है। sa_family फ़ील्ड के बाद कुल आकार 26 बाइट्स है।

संबंधित मुद्दे