2017-01-04 6 views
18

मोनो 3.12 पर, मैं अनुरोध-आधारित स्ट्रीमिंग प्रोटोकॉल को लागू करने के लिए एक टीसीपी स्ट्रीम Socket के साथ Socket.SendAsync(SocketAsyncEventArgs) का उपयोग कर रहा हूं। मैं डेटा के एकाधिक बफर सेट करने के लिए SocketAsyncEventArgs.BufferList का उपयोग कर रहा हूं।क्या एक टीसीपी सॉकेट SendAsync ऑपरेशन एक बफरलिस्ट में सभी बाइट्स को स्थानांतरित किए बिना पूरा कर सकता है?

Socket और SocketAsyncEventArgs के लिए दस्तावेज़ में, मैं के बिना सभी बाइट्स जब BufferList प्रयोग किया जाता है भेजा जा रहा है, छाप हम SocketAsyncEventArgs.BytesTransferred के खिलाफ मान्य करने के लिए है कि छोड़ने SocketAsyncEventArgs.Completed उठाया जा सकता है कि क्या कोई उल्लेख नहीं मिल रहा।

दूसरी ओर, Socket.BeginSend करता है कि गारंटी

आपका आवेदन BeginSend कहता है, प्रणाली एक अलग थ्रेड निर्दिष्ट कॉलबैक विधि निष्पादित करने के लिए उपयोग करेगा, और होगा EndSendपर ब्लॉक Socket तक बाइट्स की संख्या भेजता है या अपवाद फेंकता है।

क्या गारंटी देता है विनिर्देश जब एक SocketAsyncEventArgs.BufferList साथ SendAsync का उपयोग कर स्थानांतरित बाइट्स की संख्या के बारे में है?

मान लें कि यह कार्यक्रम SocketError.Success के साथ पूरा हुआ था।

+1

मुझे लगता है कि सवाल यह होगा: "क्या सॉकेट एसिंसेनएन्टएआरजी.कॉम्प्लेटेड हैंडलर को सॉकेट त्रुटि के बिना बुलाया जा सकता है और 'ई। बाइट्स ट्रांसफर! = लंबाई'?" जो मैं .NET Framework के तहत एकत्र कर सकता हूं उससे संभव नहीं है: http://stackoverflow.com/questions/28675811/when-i-call-wsasend-will-all-the-data-be-sent और http: // stackoverflow .com/प्रश्न/14347708/कॉलिंग-wsasend-in-complet-port – jorgebg

+0

क्या आप परीक्षण के लिए कुछ कोड प्रदान कर सकते हैं? –

+0

@DieterMeemken आपको जवाब देने के लिए परीक्षण करने की क्या आवश्यकता है _ विनिर्देश बनाने की गारंटी क्या है? जैसा कि मैंने उल्लेख किया है, मैं 'SendAsync' का उपयोग' SocketAsyncEventArgs' के साथ सेट 'बफर लिस्ट' के साथ कर रहा हूं। –

उत्तर

1

SocketAsyncEventArgs.BufferList के साथ SendAsync का उपयोग करते समय विनिर्देशन बाइट्स की संख्या के बारे में क्या गारंटी देता है?

प्रारंभ करने के लिए, ईवेंट त्रुटियों पर उठाया जा सकता है, इस मामले में आप मान सकते हैं कि सभी बाइट्स स्थानांतरित नहीं किए गए हैं। इसके लिए आपको SocketEsyncEventArgs.SocketError को SocketError.Success के लिए परीक्षण करने की आवश्यकता है। साथ ही, यदि आप 'विनिर्देश' का संदर्भ लेते हैं तो मुझे लगता है कि आपका मतलब है (माइक्रोसॉफ्ट) विंडोज सॉकेट दस्तावेज (क्योंकि आप इसे SendAsync और अन्य विवरणों के लिए लिंक करते हैं)।

सफलता के मामले में पूर्ण घटना कहलाते समय दस्तावेज कहता है या हस्तांतरित बाइट्स की संख्या के लिए तात्पर्य है, हमें कुछ कदम उठाने पड़ते हैं। पहला कदम यह देखना है कि SendAsync ओवरलैप्ड I/O का उपयोग करता है या नहीं। Overlapped Input/Output दस्तावेज़ीकरण में उस प्रश्न का उत्तर दिया गया है। अंतर्निहित परिवहन प्रदाताओं के लिए इस तंत्र के लिए कार्यान्वयन अनिवार्य है और इसलिए यह एकमात्र ओवरलैप्ड I/O तंत्र है जो विंडोज सॉकेट के लिए उपलब्ध होने की गारंटी है। इस प्रकार, SendAsync को WSA_FLAG_OVERLAPPED विशेषता के साथ सॉकेट का उपयोग करने की गारंटी है।

ध्यान दें कि SendAsync reference implementation का निरीक्षण दर्शाता है कि SendAsync वास्तव में ओवरलैप I/O के साथ WSASend का उपयोग कर रहा है, लेकिन यह केवल एक अवलोकन है।

दूसरा चरण यह निर्धारित करना है कि ओवरलैप्ड I/O हमें स्थानांतरित बाइट्स की मात्रा से संबंधित पूर्ण घटना के संकेत के बारे में बताता है। इस स्थिति को कई स्थानों पर वर्णित किया गया है, उदाहरण के लिए इस Overlapped I/I and Event Objects पृष्ठ पर: 'बफर को खपत भेजे जाने पर संकेत प्रदान किया जाएगा'। [डब्लूएसएएसएंड] फ़ंक्शन के लिए टिप्पणी अनुभाग में थोड़ा और विवरण दिया गया है: 'एक पूरा संकेत होगा, जब एक बफर (ओं) परिवहन द्वारा उपभोग किया जाता है, तो एक नियमित वस्तु या घटना वस्तु की समाप्ति का आह्वान किया जाएगा। ।

यह अभी भी इस वाक्यांश की सटीक व्याख्या के लिए कुछ जगह छोड़ देता है।असल में यह कहता है कि डेटा सॉकेट स्कोप से अंतर्निहित परिवहन तंत्र द्वारा स्वीकार और पुष्टि की गई थी। इसका मतलब यह नहीं है कि यह रिमोट एंडपॉइंट प्रोटोकॉल परत पर पहुंचा है, यह संचार प्रोटोकॉल पर निर्भर करेगा। एक टीसीपी स्ट्रीमिंग सॉकेट के लिए मैं अनुमान लगाता हूं कि यह इंगित करता है कि डेटा रिमोट एंडपॉइंट पर पहुंचा है।

निष्कर्ष यह है कि दस्तावेज गारंटी (एक गैर-त्रुटि स्थिति के लिए) है कि SendAsync पूर्ण ईवेंट केवल उस बिंदु पर उठाया जाता है जब सभी बाइट स्थानांतरित किए जाते हैं।

+0

हां, चलो 'SocketError.SUccess' के लिए केवल मान लें। मैं अपना प्रश्न संपादित करूंगा। मैं आश्वस्त नहीं हूं। जब मैं प्रलेखन से लिंक करता हूं, तो मेरा इरादा नेट मानक पुस्तकालयों से लिंक करना है जिसे सभी .NET रनटाइम्स द्वारा लागू किया जाना चाहिए, न केवल विंडोज़। विंडोज कार्यान्वयन यह एक तरीका है, लेकिन क्या यह एकमात्र सही तरीका है? –

-1

आप यहां जांच करने की कोशिश कर रहे हैं? क्या आप चिंतित हैं कि जब आप सभी बाइट भेजे जाते हैं तो आप सभी बाइट क्यों नहीं प्राप्त कर रहे हैं?

जब आप एक शॉट पर 100 बाइट भेजते हैं और दूसरी छोर पर 100 बाइट्स पढ़ने की कोशिश करते हैं, तो गारंटी नहीं है कि आपको एक शॉट पर सभी बाइट प्राप्त होंगे। इसे 1 बाइट के 100 पैकेट में तोड़ा जा सकता है। इस तरह टीसीपी काम करता है। आपको हमेशा बाइट जमा करने की आवश्यकता होती है और फिर अपने पैकेट को अलग और अलग करने की आवश्यकता होती है। इसे टीसीपी सॉकेट नलसाजी प्रयास कहा जाता है। डब्ल्यूसीएफ और उन सभी रैपर आपके लिए यह करते हैं।

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