2012-01-26 4 views
7

प्राप्त और भेजता है मैं सी # में 'सॉकेटएसिंसेन्ट आर्ट्स' वर्ग को समझने की कोशिश कर रहा हूं। http://msdn.microsoft.com/en-us/library/system.net.sockets.socketasynceventargs.aspxसी # सॉकेटएसिंसेन्ट आर्ट्स हैंडलिंग डेटा

मैं इस ट्यूटोरियल अनुसरण कर रही हूं: http://www.codeproject.com/Articles/83102/C-SocketAsyncEventArgs-High-Performance-Socket-Cod

अब मैं कैसे मैं वास्तव में अपने सर्वर के साथ डेटा की प्रक्रिया चाहिए में फंस कर रहा हूँ। मैं जो करने की कोशिश कर रहा हूं वह एक कनेक्टेड क्लाइंट के लिए सॉकेटएसिंसेन्ट आर्ग्स का उपयोग है जो बफरमेनगर में 512 बाइट्स के आवंटित बफर स्पेस के साथ है। तो मैं क्या करना चाहता हूं बाइट [] डेटा को अपनी खुद की कस्टम क्लास (क्लाइंटपैकेट) में डीकोड करना है जो बाइट [] को डीकोडिंग और पढ़ने के लिए रखता है।

यह सब कुछ ठीक है लेकिन अपने सर्वर हमेशा सवाल डेटा के साथ प्रतिक्रिया नहीं करता है:

मैं 1 प्राप्त करने और पाश के लिए SocketAsyncEventArgs का उपयोग चारों ओर, डेटा प्राप्त तो पूल जब भी से एक SocketAsyncEventArgs आवंटित कार्रवाई करने के लिए करते हैं मुझे इसे भेजने पर वापस लौटने की जरूरत है?

और रीडिंग पूर्ण होने पर सॉकेटएसिंसेन्ट आर्ट्स को कैसे पता चलता है? (जब यह बाइट [] बफर के साथ समाप्त हो जाता है, इससे पहले कि यह नए डेटा के साथ ओवर-लिखता है) जैसे कि अगर मैं वापस जवाब नहीं देता तो पूल में यह कैसे लौटाया जाता है?

उत्तर

8

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

एक बार मैं जुड़ा हुआ है और सॉकेट के लिए एक संदर्भ है है, मैं इस तरह सुन शुरू:

private void ResetBuffer(SocketAsyncEventArgs e) 
{ 
    var buffer = new Byte[SocketBufferSize]; 

    e.SetBuffer(buffer, 0, SocketBufferSize); 
} 

मैं डेटा की प्रक्रिया:

public void StartListening(SocketAsyncEventArgs e) 
{ 
    ResetBuffer(e); 
    e.Completed += SocketReceive; 

    socket.ReceiveAsync(e); 
} 

मैं एक सहायक समारोह है कि बफर रीसेट करता है जैसे:

private void SocketReceive(Object sender, SocketAsyncEventArgs e) 
{ 
    ProcessData(e.Buffer, 0, e.BytesTransferred); 

    ResetBuffer(e); 

    socket.ReceiveAsync(e); 
} 

प्रक्रिया डेटा में, आप डेटा को खींचने के लिए बाइट सरणी का उपयोग कर सकते हैं । मैं, इसका इस्तेमाल एक MemoryStream जो मैं तो मेरे वर्ग (ClientPacket के समान) में deserialize बनाने के लिए इस प्रकार है:

private void ProcessData(Byte[] data, Int32 count) 
{ 
    using (var stream = new MemoryStream(data, 0, count)) 
    { 
     var serializer = new XmlSerializer(typeof(ClientPacket)); 

     var packet = serializer.Deserialize(stream); 

     // Do something with the packet 
    } 
} 

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

खंडन का नकारात्मक हिस्सा यह है कि संदेशों को बुनियादी ढांचे द्वारा विलय किया जा सकता है जिसका अर्थ है कि आपको यह बताने का एक तरीका हो सकता है कि पहला संदेश कब समाप्त हो गया है। विशिष्ट दृष्टिकोण में आपके संदेश को 4 बाइट पूर्णांक के साथ prefacing शामिल है जो संदेश की लंबाई इंगित करता है। यदि आवश्यक हो तो मैं और विस्तार कर सकता हूं।

उम्मीद है कि मदद करता है।

+0

आपने इसे एक नए बाइट [] पर सेट करके कहा, लेकिन मैं सभी सॉकेटएसिंसेन्ट आर्ट्स में एक बड़ा बफर ब्लॉक साझा कर रहा हूं, अगर मैं एक पैकेट में उस बफर ब्लॉक से पढ़ता हूं तो बफर ब्लॉक अगले आने वाले द्वारा ओवर-लिखित हो सकता है डेटा, भले ही मैं बाइट [] सरणी की प्रतिलिपि बनाता हूं, यह डेटा भेजने/प्राप्त करने के लिए बफर ब्लॉक का उपयोग करने जा रहा है? साथ ही जब मैं किसी भी समय एक ऑपरेशन हो सकता है तो मैं उसी ऑब्जेक्ट के साथ डेटा कैसे भेजूं? –

+1

आप 2 मशीनों के बीच एक एकल सॉकेट कनेक्शन मानते हैं। कई समवर्ती कनेक्शनों को संभालने के दौरान आप केवल एक ही सॉकेटएसिंसेन्ट आर्ग का पुन: उपयोग नहीं कर सकते हैं, जो मुझे लगता है कि सवाल क्या था। (और यही है जो सॉकेटएसिंसेन्ट आर्ट्स के लिए बनाया गया है)। –

+0

धन्यवाद SonOfPirate, यह शानदार होगा अगर आप बड़ी मात्रा में डेटा प्राप्त करने के बारे में विस्तार से बता सकते हैं। विशेष रूप से स्पष्ट करें अगर मुझे अंत तक पहुंचने से पहले प्रत्येक बार ReceiveAsync को फिर से कॉल करना होगा; या फ्रेमवर्क मेरे लिए यह करेगा? –

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