
बर्कले और माइक्रोसॉफ्ट से सॉकेट मॉडल, जो कई मायनों में स्रोत कोड स्तर पर संगत हैं, व्यवहार में इतना क्रॉस-प्लेटफॉर्म नहीं है।
आइए उनके कार्यान्वयन में कुछ मुश्किल अंतरों को देखें, जो कि एक ओएस में एक प्रक्रिया से दूसरे ओएस में एक प्रक्रिया के पुनर्निर्देशित नेटवर्क कॉल को क्रॉस-प्लेटफॉर्म आरपीसी लिखते समय पाए गए थे।
सॉकेट प्रकार- बीएसडी: int
- जीत: शून्य * // मैक्रो स्टॉक
जब तक प्रोसेसर की क्षमता 32 बिट्स होती है, तब तक इंटरचेंज के साथ कोई समस्या नहीं होती है। विंडोज में 64 बिट्स पर, SOCKET प्रकार आकार में 2 गुना बड़ा है।
बीएसडी सॉकेट डिस्क्रिप्टर फ़ाइल डिस्क्रिप्टर से अलग नहीं है, जिसका अर्थ है कि कुछ सिस्टम कॉल एक साथ सॉकेट और फ़ाइलों दोनों के डिस्क्रिप्टर द्वारा स्वीकार किए जाते हैं (उदाहरण के लिए, जैसे "शायद ही कभी" कॉल जैसे करीबी (), fcntl () और ioctl ())।
एक साइड इफ़ेक्ट भी है जो न केवल विकट परिस्थितियों में प्रकट होता है, अर्थात् बर्कले मॉडल का समर्थन करने वाले सिस्टम पर सॉकेट डिस्क्रिप्टर का संख्यात्मक मान आमतौर पर एक छोटी संख्या (100 से कम) होता है, और क्रमिक रूप से बनाए गए डिस्क्रिप्टर 1. भिन्न भिन्न होते हैं। Microsoft मॉडल में, ऐसा डिस्क्रिप्टर तुरंत 200 से अधिक (लगभग), और क्रमिक रूप से निर्मित वर्णनकर्ता आकार (सॉकेट) द्वारा भिन्न होते हैं।
हैंडलिंग में त्रुटि- बीएसडी: कॉल्स रिटर्न -1, वैश्विक चर अशुद्ध सेट है।
- जीत: कॉल -1 (मैक्रो SOCKET_ERROR), स्थिति WSAGetLastError () का उपयोग करके प्राप्त की जाती है।
Errno स्थिरांक और विंडोज त्रुटि कोड पूरी तरह से अलग अर्थ हैं।
सॉकेट्स बनाना:सॉकेट (इंट अफ, इंट प्रकार, इंट प्रोटोकॉल);
पहले तर्क के लिए स्थिरांक का बीएसडी और विंडोज पर पूरी तरह से अलग अर्थ है। दूसरे के लिए, वे अभी भी समान हैं।
सॉकेट कॉन्फ़िगर करें- बीएसडी:
getsockopt (int sockfd, int level, int option_name, void * option_value, socklen_t * option_len);
setsockopt (int sockfd, int level, int option_name, void const * option_value, socklen_t option_len)
- जीत:
getsockopt (SOCKET sock, int level, int option_name, void * option_value, socklen_t * option_len);
setsockopt (SockET sock, int level, int option_name, void const * option_value, socklen_t option_len)
दूसरे और तीसरे तर्क के लिए ध्वज स्थिरांक का बीएसडी और विंडोज पर पूरी तरह से अलग अर्थ है।
सॉकेट्स को कॉन्फ़िगर करें 2- BSD: fcntl (int fd, int cmd, ...);
- जीत: ioctlsocket (SOCKET जुर्राब, लंबी cmd, लंबे अहस्ताक्षरित * arg);
एकमात्र पूरी तरह से सही मैपिंग: fcntl (डिस्क्रिप्टर, F_SETFL, O_NONBLOCK) -> ioctlsocket (डिस्क्रिप्टर, FIONBIO, मान O_NBLBLOCK के साथ चर का पता)। झंडे के संख्यात्मक मूल्यों को लक्ष्य प्रणाली के सापेक्ष समझा जाना चाहिए (वे बीएसडी और विंडोज पर अलग हैं)।
उसी समय, fcntl (डिस्क्रिप्टर, F_GETFL) जैसी क्वेरी 0 या O_RRWR वापस कर सकती है।
कॉन्फ़िगर करें सॉकेट 3- BSD: ioctl (int fd, int cmd, ...);
- जीत: ioctlsocket (SOCKET जुर्राब, लंबी cmd, लंबे अहस्ताक्षरित * arg);
पहले तर्क के रूप में सॉकेट के साथ ioctl () के वास्तविक उपयोग के मामलों की अभी तक पहचान नहीं की गई है।
डीएनएस के साथ काम करेंgetaddrinfo (चार कांस्ट * नोड, चार कांस्ट * सर्विस, स्ट्रक्चर एड्रीनो कॉन्स * संकेत, स्ट्रक्चर एड्रीनो ** ब्लर)
- बीएसडी:
स्ट्रक्चर एड्रीनो
{
int ai_flags;
int ai_family;
int ai_socktype;
int ai_protocol;
socklen_t ai_addrlen;
संरचना sockaddr * ai_addr;
char * ai_canonname;
संरचना परिशिष्ट * ai_next;
};
- जीत:
टाइपडिफ संरचना एड्रीनो
{
int ai_flags;
int ai_family;
int ai_socktype;
int ai_protocol;
size_t ai_addrlen;
char * ai_canonname;
संरचना sockaddr_ * ai_addr;
संरचना addrinfo_ * ai_next;
} ADDRINFOA, * PADDRINFOA;
इन संरचनाओं के आक्रमणकारियों को ध्यान से देखें। ai_addr और ai_canonname की संरचना की शुरुआत के सापेक्ष अलग-अलग ऑफसेट हैं। डेवलपर्स ने बस उन्हें स्वैप किया (मिश्रित किया?)।
डेटा अग्रेषण- बीएसडी:
recv (int sockfd, void * बफर, size_t लंबाई, int ध्वज);
recvfrom (int sockfd, void * बफर, size_t लंबाई, int ध्वज, संरचना sockaddr * से, socklen_t * fromlen);
send (int sockfd, void const * बफर, size_t लंबाई, int झंडे);
sendto (int sockfd, void const * बफर, size_t length, int ध्वज, संरचना sockaddr const * to, socklen_t tolen);
- जीत:
recv (SockET जुर्राब, शून्य * बफर, size_t लंबाई, int झंडे);
recvfrom (SOCKET जुर्राब, शून्य * बफर, size_t लंबाई, int झंडे, संरचना sockaddr * से, socklen_t * fromlen);
भेजें (SockET जुर्राब, शून्य कास्ट * बफर, size_t लंबाई, int झंडे);
sendto (SockET sock, void const * बफर, size_t length, int ध्वज, संरचना sockaddr const * to, socklen_t tolen);
चौथे तर्क के झंडे बीएसडी और विंडोज पर पूरी तरह से अलग अर्थ हैं।
संचालन की प्रतीक्षा में- बीएसडी: पोल (स्ट्रक्चर पोलफड * एफडीएस, एनडीएसडीटी / एनएफडीएस, इंट टाइमआउट);
संरचना प्रदूषण
{
int fd;
छोटी घटनाओं;
छोटी परिक्रमा;
};
- जीतो: WSAPoll (स्ट्रक्चर पोलफड * fds, nfds_t nfds, int timeout);
टाइपडिफ संरचना पोलफेड
{
सॉकेट जुरमाना;
WORD ईवेंट;
WORD घूमता है;
} WSAPOLLFD, * PWSAPOLLFD;
पोलड संरचना के दूसरे और तीसरे आक्रमणकारियों के लिए ध्वज स्थिरांक का बीएसडी और विंडोज पर पूरी तरह से अलग मूल्य है। WSAPoll () केवल विंडोज 6 वें संस्करण (विस्टा) और बाद में उपलब्ध है।
संचालन की प्रतीक्षा में २- BSD: select (int nfds, fd_set * readfds, fd_set * writefds, fd_set * errorfds, स्ट्रक्चर टाइमवेल * टाइमआउट);
टाइप्डिफ़ संरचना
{
लंबी fds_bits [FD_SETSIZE / 8 * sizeof (लंबी)];
} fd_set;
- जीतो: सेलेक्ट (int nfds, FDSET * readfds, FDSET * writefds, FDSET * errorfds, स्ट्रक्चर टाइमवाल * टाइमआउट);
typedef संरचना fd_set
{
अहस्ताक्षरित fd_count;
SOCKET fd_array [FD_SETSIZE];
} FDSET, * PFDSET;
चयन में एक समस्या तब होती है जब fd_set संरचना मैप की जाती है। याद रखें कि कैसे () काम करता है। यह कॉल सॉकेट्स के तीन सेटों को स्वीकार करता है: कुछ समय के लिए पढ़ने, लिखने और त्रुटियों की जाँच के लिए। आप मैक्रो FD_SET (सॉकेट, सेट) द्वारा इनमें से किसी एक सेट के सत्यापन के लिए अपना सॉकेट जोड़ सकते हैं, स्थिरता की जांच कर सकते हैं - FD_ISSET (सॉकेट, सेट), सेट से एक सॉकेट हटाएं - FD_CLR (सॉकेट, सेट), सब कुछ हटाएं - FD_ZERO (सेट) । कॉल के बाद, चयन () इसी सेट में छोड़ देता है केवल उन सॉकेट्स, जो अंतिम तर्क द्वारा निर्दिष्ट टाइमआउट के दौरान, अपेक्षित स्थिति प्राप्त कर चुके हैं।
एक बीएसडी के लिए, एक सॉकेट को एक सेट में डालने से अंतिम बिट में लंडिंग होती है जैसे कि उसका सीरियल नंबर संख्यात्मक विवरणकर्ता के बराबर होता है। FD_SETSIZE आमतौर पर 1024 है। चयन करने के लिए पहला तर्क () तीन सेटों में से किसी एक में सॉकेट डिस्क्रिप्टर का अधिकतम संख्यात्मक मान है। यह देखते हुए कि fds_bits सरणी में थोड़ी सी सेटिंग को विशेष रूप से सीमा की जांच किए बिना किया जाता है, यह स्पष्ट हो जाता है कि सॉकेट विवरणक मूल्य> = FD_SETSIZE के साथ, प्रोग्राम व्यवहार अपरिभाषित है। इस तरह के चयन के कुछ अविश्वसनीय कार्यान्वयन कंजूस कंप्यूटर का एक अवशेष है। वैसे, यहाँ किस स्थिति में int -> SOCKET और इसके विपरीत का अप्रत्यक्ष रूपांतरण महत्वपूर्ण है।
विंडोज के लिए, कुछ सेट में एक सॉकेट डालकर fd_cray एरे में fd_count इंडेक्स में डालना और बाद में इसे बढ़ाना शामिल है। FD_SETSIZE आमतौर पर 64 है। हालांकि, पहले तर्क () का चयन करने के लिए पूरी तरह से नजरअंदाज कर दिया जाता है।