नोट: मुझे इस प्रश्न की लंबाई के लिए माफी माँगने दो, मुझे इसमें बहुत सारी जानकारी डालना पड़ा। मुझे आशा है कि बहुत से लोगों को बस इसे स्किम करने और धारणाएं करने का कारण नहीं बनता है। कृपया पूरी तरह से पढ़ें। धन्यवाद।लाइन आधारित नेटवर्क I/O धाराओं को संभालने के लिए एक अच्छी विधि क्या है?
मेरे पास सॉकेट में आने वाले डेटा की एक स्ट्रीम है। यह डेटा लाइन उन्मुख है।
मैं .NET (BeginRead, आदि ..) के एपीएम (Async प्रोग्रामिंग विधि) का उपयोग कर रहा हूँ। यह स्ट्रीम आधारित I/O का उपयोग करना रोकता है क्योंकि Async I/O बफर आधारित है। डेटा को दोबारा लोड करना और इसे स्ट्रीम में भेजना संभव है, जैसे मेमोरी स्ट्रीम, लेकिन वहां भी समस्याएं हैं।
समस्या यह है कि मेरी इनपुट स्ट्रीम (जिसका मेरा कोई नियंत्रण नहीं है) मुझे कोई जानकारी नहीं देता है कि स्ट्रीम कितनी देर तक है। यह बस यह की तरह लग रही न्यू लाइन लाइनों की एक धारा है:
COMMAND\n
...Unpredictable number of lines of data...\n
END COMMAND\n
....repeat....
तो, एपीएम का उपयोग कर, और तब से मैं कितनी देर तक किसी भी डेटा सेट हो जाएगा पता नहीं है, यह संभावना है कि डेटा के ब्लॉक बफर पार जाएगा सीमाओं को एकाधिक पढ़ने की आवश्यकता होती है, लेकिन उन एकाधिक पढ़ने से डेटा के कई ब्लॉक भी फैले होंगे।
उदाहरण:
Byte buffer[1024] = ".................blah\nThis is another l"
[another read]
"ine\n.............................More Lines..."
मेरी पहली सोचा एक StringBuilder उपयोग करने के लिए और बस एस.बी. के लिए बफर पंक्तियां जोड़ रहा था। यह कुछ हद तक काम करता है, लेकिन मुझे डेटा के ब्लॉक निकालने में मुश्किल होती है। मैंने न्यूलाइन डेटा पढ़ने के लिए स्ट्रिंग रीडर का उपयोग करने का प्रयास किया लेकिन यह जानने का कोई तरीका नहीं था कि आपको पूरी लाइन मिल रही है या नहीं, क्योंकि स्ट्रिंग रीडर अंतिम ब्लॉक के अंत में आंशिक रेखा देता है, इसके बाद नल आफ्टरवार्ड लौटता है। यह जानने का कोई तरीका नहीं है कि क्या लौटाया गया था डेटा की एक पूर्ण रूपरेखा रेखा थी।
उदाहरण:
// Note: no newline at the end
StringBuilder sb = new StringBuilder("This is a line\nThis is incomp..");
StringReader sr = new StringReader(sb);
string s = sr.ReadLine(); // returns "This is a line"
s = sr.ReadLine(); // returns "This is incomp.."
क्या बदतर है, कि अगर मैं सिर्फ आंकड़ों के जोड़कर रखने के लिए, बफ़र्स बड़ा और बड़ा मिलता है, और इस के बाद से एक बार हुआ है कि एक अच्छा नहीं है पर हफ्तों या महीनों के लिए चला सकते है उपाय।
मेरा अगला विचार एसबी से डेटा के ब्लॉक को हटाने के लिए था जैसा कि मैंने उन्हें पढ़ा था। इसके लिए अपना खुद का रीडलाइन फ़ंक्शन लिखना आवश्यक था, लेकिन फिर मैं पढ़ने और लिखने के दौरान डेटा लॉक कर रहा हूं। साथ ही, डेटा के बड़े ब्लॉक (जिसमें सैकड़ों रीड और डेटा के मेगाबाइट शामिल हो सकते हैं) को पूरे बफर को स्कैनिंग की आवश्यकता होती है जो न्यूलाइन की तलाश में होती है। यह कुशल और सुंदर बदसूरत नहीं है।
मैं कुछ ऐसा ढूंढ रहा हूं जिसमें StreamReader/Writer की सादगी है Iync I/O की सुविधा के साथ।
मेरा अगला विचार मेमोरीस्ट्रीम का उपयोग करना था, और डेटा के ब्लॉक को मेमोरी स्ट्रीम में लिखना था, फिर स्ट्रीम स्ट्रीमर को स्ट्रीम में संलग्न करें और रीडलाइन का उपयोग करें, लेकिन फिर मुझे यह जानने के साथ समस्याएं हैं कि बफर में आखिरी पढ़ना है या नहीं एक पूर्ण रेखा या नहीं, साथ ही स्ट्रीम से "बासी" डेटा को हटाने के लिए भी मुश्किल है।
मैंने सिंक्रोनस रीड के साथ थ्रेड का उपयोग करने के बारे में भी सोचा। इसका लाभ यह है कि StreamReader का उपयोग करके, यह हमेशा टूटी हुई कनेक्शन स्थितियों को छोड़कर रीडलाइन() से एक पूर्ण रेखा वापस कर देगा। हालांकि इसमें कनेक्शन को रद्द करने के साथ समस्याएं हैं, और कुछ प्रकार की नेटवर्क समस्याओं के परिणामस्वरूप विस्तारित अवधि के लिए अवरुद्ध सॉकेट को लटका दिया जा सकता है। मैं async IO का उपयोग कर रहा हूं क्योंकि मैं डेटा प्राप्त करने वाले प्रोग्राम के जीवन के लिए धागा बांधना नहीं चाहता हूं।
कनेक्शन लंबे समय तक चल रहा है।और समय के साथ डेटा प्रवाह जारी रहेगा। आंशिक कनेक्शन के दौरान, डेटा का एक बड़ा प्रवाह होता है, और एक बार प्रवाह होने के बाद सॉकेट वास्तविक समय के अपडेट के लिए खुला रहता है। मुझे पता नहीं है कि प्रारंभिक प्रवाह "समाप्त" हो गया है, क्योंकि यह जानने का एकमात्र तरीका यह है कि तुरंत कोई डेटा नहीं भेजा जाता है। इसका मतलब है कि मैं प्रसंस्करण से पहले प्रारंभिक डेटा लोड को समाप्त करने की प्रतीक्षा नहीं कर सकता, मैं अंदर आने के रूप में "वास्तविक समय में" बहुत अधिक अटक गया हूं।
तो, क्या कोई इस स्थिति को संभालने के लिए एक अच्छी विधि सुझा सकता है एक तरह से जो अत्यधिक जटिल नहीं है? मैं वास्तव में यह जितना संभव हो उतना सरल और सुरुचिपूर्ण होना चाहता हूं, लेकिन मैं सभी किनारे के मामलों के कारण अधिक से अधिक जटिल समाधानों के साथ आ रहा हूं। मुझे लगता है कि मैं जो कुछ चाहता हूं वह कुछ प्रकार का फीफो है जिसमें मैं आसानी से अधिक डेटा जोड़ना जारी रख सकता हूं, जबकि एक ही समय में डेटा को पॉप आउट करना जो कुछ मानदंडों से मेल खाता है (यानी, न्यूलाइन समाप्त स्ट्रिंग्स)।
मैंने सोचा कि यह भी एक दिलचस्प समस्या थी, इसलिए मैंने सीसीआर के साथ इसे हल करने के बारे में एक पोस्ट लिखा जो आप http: //iodyner.spaces.live.com, यदि आप रुचि रखते हैं ... –