सॉकेट ओवरलैप किए गए i/O बनाम ब्लॉकिंग/


सारांश


यह आलेख बताता है कि सॉकेट के ओवरलैप किए गए i/o विशेषता और सॉकेट ब्लॉकिंग या nonblocking मोड के बीच अंतर है।

अधिक जानकारी


जब सॉकेट बनाया जाता है, तो डिफ़ॉल्ट रूप से यह एक ब्लॉकिंग सॉकेट है। आप IOCTLsocket API कॉल, WSAEventSelect, या WSAAysncSelect में FIONBIO आदेश का उपयोग कर सकते हैं सॉकेट मोड nonblocking करने के लिए ब्लॉकिंग से परिवर्तित करने के लिए। Winsock कॉल तुरंत पूरा नहीं कर सकता, तो कॉल विफल रहता है और WSAGetLastError एक WSAEWOULDBLOCK त्रुटि देता है, तो यह एक nonblocking सॉकेट, या कॉल ब्लॉक कार्रवाई पूर्ण करता है जब तक कि यह एक ब्लॉकिंग सॉकेट है। सॉकेट ओवरलैप किए गए i/o विशेषता सॉकेट ब्लॉकिंग या nonblocking मोड से भिन्न है। यद्यपि वर्तमान Winsock कार्यान्वयन nonblocking सॉकेट मोड के लिए ओवरलैप किए गए i/o विशेषता की आवश्यकता है, वे अवधारणात्मक स्वतंत्र हैं और उनके प्रोग्रामिंग मॉडल भी अलग है। ओवरलैप किए गए i/o विशेषता के साथ एक सॉकेट बनाने के लिए, आप या तो सॉकेट API या WSASocket API WSA$FLAG$OVERLAPPED ध्वज सेट के साथ उपयोग कर सकते हैं। यदि कोई ओवरलैप किए गए i/o कार्रवाई तुरंत पूर्ण नहीं कर सकते हैं, तो कॉल विफल रहता है और WSAGetLastError या GetLastError वापसी WSA$IO$PENDING या ERROR$IO$PENDING, जो वास्तव में एक ही परिभाषित है WSA$IO$PENDING के रूप में है। अतिरिक्त जानकारी के लिए, कृपया Microsoft नॉलेज बेस में निम्न आलेख देखें:
179942 INFO: WSA$FLAG]OVERLAPPED गैर-ब्लॉकिंग सॉकेट के लिए आवश्यक है
सॉकेट बनने के बाद, सॉकेट ओवरलैप किए गए विशेषता को परिवर्तित करने का कोई तरीका नहीं है कि कृपया ध्यान दें। हालाँकि, आप एक ही थ्रेड में सभी क्रमिक सॉकेट कॉल के लिए ओवरलैप किए गए विशेषताएँ परिवर्तित करने के लिए एक INVALID-SOCKET सहित किसी भी सॉकेट हैंडल पर SO$OPENTYPE विकल्प के साथ setsockopt API कॉल कर सकते हैं। डिफ़ॉल्ट SO$OPENTYPE विकल्प मान 0 है, जो ओवरलैप की गई विशेषता सेट करता है। सभी शून्य न हो विकल्प मान सॉकेट सिंक्रोनस बनाते हैं और इसे ताकि आप किसी पूर्ण फ़ंक्शन का उपयोग नहीं कर सकें. सॉकेट के ओवरलैप किए गए i/o विशेषता सेट करके इसका अर्थ यह नहीं है कि सॉकेट एक ओवरलैप किए गए i/o कार्रवाई करेगा. उदाहरण के लिए, यदि आप पूर्ण होने के फ़ंक्शन और WSARecv और WSASend में ओवरलैप की गई संरचना दोनों के लिए नल निर्दिष्ट करते हैं, या आप बस recv कॉल करते हैं या फ़ंक्शन भेजते हैं, तो वे ब्लॉकिंग फैशन में पूर्ण हो जाएँगे. यह सुनिश्चित करने के लिए कि i/o एक ओवरलैप किए गए फैशन में किया जाता है, आपको आपके द्वारा उपयोग किए जाने वाले फ़ंक्शन के आधार पर अपने i/O फ़ंक्शन में एक ओवरलैप की गई संरचना प्रदान करने की आवश्यकता है।

ओवरलैप किए गए i/O

Winsock 1 में, आप सॉकेट API का उपयोग कर एक ओवरलैप किए गए सॉकेट बनाएँ, और Win32 फ़ाइल i/O API ReadFile, ReadFileEx, WriteFileEx सॉकेट हैंडल पर ओवरलैप किए गए i/o करने के लिए का उपयोग करें। Winsock 2 में, आप WSASocket WSA$FLAG$OVERLAPPED ध्वज के साथ, या बस सॉकेट API का उपयोग कर के साथ एक ओवरलैप सॉकेट बनाएँ। आप ऊपर Win32 फ़ाइल i/O APIs या Winsock 2 WSASend, WSASendTo, WSARecv, और WSARecvFrom एक ओवरलैप किए गए i/o कार्रवाई आरंभ करने के लिए उपयोग कर सकते हैं। शून्य TCP स्टैक प्राप्त करें और बफ़र भेजने के लिए सेट करने के लिए SO$RCVBUF और SO$SNDBUF विकल्प का उपयोग करते हैं, तो आप मूल रूप से आपके i/o कॉल में उपलब्ध बफ़र का उपयोग कर i/o सीधे निष्पादित करने के लिए TCP स्टैक निर्देश। इसलिए, overlapped सॉकेट i/o के nonblocking लाभ के अतिरिक्त, अन्य लाभ बेहतर प्रदर्शन है क्योंकि आप TCP स्टैक बफ़र और प्रत्येक i/o कॉल के लिए उपयोगकर्ता बफ़र के बीच एक बफ़र प्रतिलिपि सहेजें। लेकिन आप यह ओवरलैप किए गए ऑपरेशन के लिए प्रस्तुत किया है एक बार और ओवरलैप किए गए ऑपरेशन पूरा होने से पहले आप उपयोगकर्ता बफ़र का उपयोग नहीं करते सुनिश्चित करने के लिए है। ओवरलैप किए गए i/o कार्रवाई पूर्ण है या नहीं यह निर्धारित करने के लिए, आप निम्न विकल्पों में से एक का उपयोग कर सकते हैं:
  • आप i/o कॉल में उपयोग किए गए किसी ओवरलैप किए गए संरचना में ईवेंट हैंडल प्रदान कर सकते हैं और ईवेंट हैंडल पर संकेत करने के लिए प्रतीक्षा कर सकते हैं.
  • GetOverlappedResult या WSAGetOverlappedResult का उपयोग करें ओवरलैप किए गए i/o ऑपरेशन की स्थिति को पोल करने के लिए। Windows NT पर, आप नल ओवरलैप किए गए संरचना में इवेंट हैंडल के रूप में निर्दिष्ट कर सकते हैं। हालाँकि, Windows 95 पर ओवरलैप किए गए संरचना मैन्युअल रीसेट इवेंट हैंडल शामिल करने के लिए की आवश्यकता है। WSAGetOverlappedResult पर Windows 98 और Windows मिलेनियम संस्करण (ME) इस तरह संशोधित किया गया है कि यह Windows NT की तरह व्यवहार करेगा और भी पूर्ण स्थिति ओवरलैप किए गए संरचना में कोई नल इवेंट हैंडल के साथ poll कर सकते हैं।
  • ReadFileEx, WriteFileEx, WSARecv, WSARecvFrom, WSASend, या WSASendTo का उपयोग करें और जब ओवरलैप किए गए i/o कार्रवाई पूर्ण हो गया है, तो कॉल करने के लिए कोई पूर्ण फ़ंक्शन प्रदान करने के लिए चुनें। यदि आप पूरा फ़ंक्शन प्रकिया का उपयोग करें, कुछ बिंदु पर आप ओवरलैप किए गए i/o कार्रवाई जारी करने के बाद आप एक Win32 प्रतीक्षा फ़ंक्शन या प्रतीक्षा फ़ंक्शन का WSA संस्करण जारी करने के लिए एक nonsignaled हैंडल पर प्रतीक्षा करने के लिए अपने वर्तमान थ्रेड एक चेतावनी योग्य प्रतीक्षा स्थिति में रखने के लिए की आवश्यकता है। जब ओवरलैप किए गए i/o कार्रवाई पूर्ण हो जाती है, तो आपका पूरा होने का कार्य कहा जाता है, आपका प्रतीक्षा फ़ंक्शन WAIT$IO$COMPLETION वापस जाने जा रहा है, और आपका चेतावनी योग्य प्रतीक्षा थ्रेड वेक हो जाता है.
  • GetQueuedCompletionStatus का उपयोग करें और एक सॉकेट, ओवरलैप किए गए i/o विशेषता सेट के साथ, Windows NT i/O कम्प्लीशन पोर्ट (IOCP) के साथ संबद्ध करें। IOCP के साथ, आप एक पूरा समारोह की आपूर्ति की जरूरत नहीं है, संकेत करने के लिए एक घटना संभाल पर प्रतीक्षा करें, या ओवरलैप किए गए ऑपरेशन की स्थिति सर्वेक्षण. एक बार जब आप IOCP बनाएँ और IOCP करने के लिए अपने ओवरलैप किए गए सॉकेट हैंडल जोड़ने के लिए, आप ऊपर उल्लेख किया i/O APIs में से किसी का उपयोग करके ओवरलैप किए गए कार्रवाई प्रारंभ कर सकते हैं (recv, recvfrom, send, या sendto को छोड़कर).। आप अपने कार्यकर्ता थ्रेड ब्लॉक GetQueuedCompletionStatus API पर एक i/o पूरा पैकेट के लिए प्रतीक्षा कर रहा होगा। जब कोई ओवरलैप किया गया i/o पूरा हो जाता है, तो IOCP पर एक i/o पूरा पैकेट आता है और GetQueuedCompletionStatus देता है। IOCP एक स्केलेबल, उच्च थ्रूपुट सर्वर बहुत सरल थ्रेडिंग और अधिव्याप्त i/o कार्रवाई पर कोड ब्लॉकिंग का उपयोग कर एक स्केलेबल, उच्च थ्रूपुट सर्वर लिखने के लिए Windows NT ऑपरेटिंग सिस्टम समर्थन है। इस प्रकार Windows NT IOCPs के साथ ओवरलैप किए गए सॉकेट i/o का उपयोग करने का एक महत्वपूर्ण प्रदर्शन लाभ हो सकता है।

ब्लॉक करना और अवरोधित करना मोड

जब सॉकेट बनाया जाता है, तो डिफ़ॉल्ट रूप से यह एक ब्लॉकिंग सॉकेट है। ब्लॉकिंग मोड सॉकेट i/o कार्रवाई के अंतर्गत, कनेक्ट करें और कार्रवाई प्रश्न में कार्रवाई पूर्ण होने तक सभी ब्लॉक स्वीकार करें। सॉकेट कार्रवाई मोड nonblocking मोड nonblocking करने के लिए ब्लॉकिंग मोड से परिवर्तित करने के लिए, आप या तो WSAAsyncSelect, WSAEventSelect, या ioctlsocket API कॉल में FIONBIO आदेश का उपयोग कर सकते हैं। WSAAsyncSelect Windows संदेशों के लिए सॉकेट सूचनाएँ मैप करें और किसी एकल थ्रेडेड GUI अनुप्रयोग के लिए सबसे अच्छा मॉडल है। WSAEventSelect संकेतन इवेंट पर सॉकेट सूचना की प्रकृति निर्धारित करने के लिए WSAEnumNetworkEvents का उपयोग करता है और एक इवेंट संकेत द्वारा सॉकेट सूचनाएँ मैप करता है। यह एक संदेश पंप, जैसे किसी Windows NT सेवा अनुप्रयोग की कमी गैर-GUI अनुप्रयोगों के लिए एक उपयोगी मॉडल है। IOCtlsocket API कॉल में FIONBIO आदेश सॉकेट nonblocking मोड में भी रखता है। लेकिन आप चयनएपीआई का उपयोग करके सॉकेट की स्थिति को पोल करने की जरूरत है। अद्यतन: ओवरलैप किए गए recv के साथ शून्य करने के लिए SO$RCVBUF सेट करना Windows 2000 के लिए आवश्यक नहीं है, जो सीधे अनुप्रयोग के recv बफ़र के लिए डेटा की प्रतिलिपि बना सकता है. Windows 2000 पर ओवरलैप किए गए भेजें के साथ शून्य करने के लिए SO$SNDBUF सेट कर रहा है अभी भी Windows NT 4.0 पर के रूप में एक स्मृति प्रतिलिपि को सहेजने का एक ही लाभ है। यह भी महत्वपूर्ण है कि अनुप्रयोग समस्याओं कई बकाया ओवरलैप किए गए भेजें या recv's यदि अनुप्रयोग संबंधित स्टैक बफ़र 0 पर सेट करता है।