2008-08-19 13 views
12

मैं पढ़ रहा है जब एक StreamReader का उपयोग कर एक HttpWebResponse की() धारा GetResponseStream द्वारा वापस पढ़ने के लिए एक "chunked" प्रतिक्रिया समस्या हो रही है:पढ़ना "chunked" के साथ प्रतिक्रिया HttpWebResponse

// response is an HttpWebResponse 
StreamReader reader = new StreamReader(response.GetResponseStream()); 
string output = reader.ReadToEnd(); // throws exception... 

जब reader.ReadToEnd() विधि है कहा जाता है कि मुझे निम्न सिस्टम मिल रहा है .IO.IOException: परिवहन कनेक्शन से डेटा पढ़ने में असमर्थ: कनेक्शन बंद था।

उपरोक्त कोड ठीक काम करता है जब सर्वर "गैर-खंडित" प्रतिक्रिया देता है।

एकमात्र तरीका जिसे मैं इसे काम करने में सक्षम हूं, प्रारंभिक अनुरोध (HTTP/1.1, डिफ़ॉल्ट के बजाय) के लिए HTTP/1.0 का उपयोग करना है, लेकिन यह एक लंगड़ा काम की तरह लगता है।

कोई विचार?


@Chuck

आपका समाधान बहुत अच्छी काम करता है। यह अभी भी अंतिम पढ़ने() पर एक ही IOExeception फेंकता है। लेकिन स्ट्रिंगबिल्डर की सामग्री का निरीक्षण करने के बाद ऐसा लगता है कि सभी डेटा प्राप्त हुए हैं। तो शायद मुझे रीड() को रीक-कैच में लपेटने और "त्रुटि" निगलने की आवश्यकता है।

+0

chunked प्रतिक्रिया पढ़ने के लिए, आप http://en.wikipedia.org/wiki/Chunked_transfer_encoding –

+0

मैं नेट 4.6 के साथ इस व्यवहार दिखाई दे रही है पालन करने की आवश्यकता PowerDNS 3.4.5 HTTP REST API से कनेक्ट हो रहा है। कामकाज मदद नहीं करते हैं। अगर मैं अपवाद निगलता हूं, तो मैं प्रतिक्रिया का हिस्सा खो देता हूं। –

उत्तर

4

इसने इसे "खंडित" प्रतिक्रिया के साथ आजमाया नहीं है, लेकिन इस काम को कुछ पसंद आएगा?

StringBuilder sb = new StringBuilder(); 
Byte[] buf = new byte[8192]; 
Stream resStream = response.GetResponseStream(); 
string tmpString = null; 
int count = 0; 
do 
{ 
    count = resStream.Read(buf, 0, buf.Length); 
    if(count != 0) 
    { 
      tmpString = Encoding.ASCII.GetString(buf, 0, count); 
      sb.Append(tmpString); 
    } 
}while (count > 0); 
+4

यह मल्टीबाइट एन्कोडिंग (यानी ASCII नहीं) के लिए खतरनाक है क्योंकि इस बात की कोई गारंटी नहीं है कि पठन को चार सीमाओं के साथ गठबंधन किया जाएगा। – spender

+2

@Chuck आप केवल ASCII का उपयोग नहीं कर सकते हैं, आपको यह पता लगाने की आवश्यकता है कि वास्तव में कौन सी एन्कोडिंग का उपयोग किया जा रहा है, यानी सामग्री-प्रकार के माध्यम से, और उसके बाद "गेटस्ट्रिंग" –

0

क्रेग, धारा देखे बिना आप इसे एक छोटे से डिबग मुश्किल है पढ़ रहे हैं लेकिन शायद आप इस के लिए गिनती चर की बदल सकता है:

count = resStream.Read(buf, 0, buf.Length-1); 

यह एक हैक का एक सा , लेकिन अगर अंतिम पठन आपको मार रहा है और यह किसी भी डेटा को वापस नहीं कर रहा है तो सैद्धांतिक रूप से यह समस्या से बच जाएगा। मुझे अभी भी आश्चर्य है कि धारा क्यों कर रही है।

0

मुझे एक ही समस्या है (जिस तरह से मैं यहां समाप्त हुआ :-)। अंततः इस तथ्य को ट्रैक किया कि खंडित धारा मान्य नहीं थी - अंतिम शून्य लंबाई का हिस्सा गायब था। मैं निम्नलिखित कोड के साथ आया जो वैध और अमान्य चंकित धाराओं दोनों को संभालता है।

using (StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8)) 
{ 
    StringBuilder sb = new StringBuilder(); 

    try 
    { 
     while (!sr.EndOfStream) 
     { 
      sb.Append((char)sr.Read()); 
     } 
    } 
    catch (System.IO.IOException) 
    { } 

    string content = sb.ToString(); 
} 
+2

का उपयोग करने के लिए चारों ओर कास्टिंग खतरनाक है क्योंकि यह पूरी तरह से अनदेखा करता है मल्टीबाइट एन्कोडिंग्स। – spender

1

मैं एक ही समस्या पर काम कर रहा हूं। .NET HttpWebRequest और HttpWebRequest कुकीज़ को संभालती है और स्वचालित रूप से रीडायरेक्ट होती है लेकिन वे स्वचालित रूप से प्रतिक्रिया शरीर पर खंडित सामग्री को संभाल नहीं पाते हैं।

शायद यह इसलिए है क्योंकि खंडित सामग्री में सरल डेटा से अधिक हो सकता है (यानी: खंड नाम, पिछला शीर्षलेख)।

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

समस्या को हल करने के लिए स्ट्रीम को मैन्युअल रूप से पार्स करना आवश्यक है, प्रत्येक खंड (साथ ही सीआर एलएफ डिलीमीटर) से खंड आकार को हटाने, अंतिम खंड का पता लगाने और केवल खंड डेटा को रखने के लिए आवश्यक है। वहां कहीं भी एक पुस्तकालय है जो ऐसा करता है, मुझे अभी तक यह नहीं मिला है।

उपयोगी संसाधन:

http://en.wikipedia.org/wiki/Chunked_transfer_encoding http://tools.ietf.org/html/rfc2616#section-3.6.1

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