2008-12-30 15 views
7

मैं सी # में एक वेब सर्वर आवेदन लिख रहा हूँ और एक अंतर्निहित NetworkStream से पढ़ने के लिए StreamReader वर्ग का उपयोग कर:.NET में StreamReader.ReadLine() द्वारा पढ़े गए वर्णों की संख्या को सीमित कैसे करें?

NetworkStream ns = new NetworkStream(clientSocket); 
StreamReader sr = new StreamReader(ns); 
String request = sr.ReadLine(); 

इस कोड Dos हमले का खतरा है क्योंकि अगर हमलावर कभी नहीं डिस्कनेक्ट हम लाइन पढ़ने खत्म कभी नहीं होगा है। क्या .NET में StreamReader.ReadLine() द्वारा पढ़े गए वर्णों की संख्या को सीमित करने का कोई तरीका है?

उत्तर

10

आपको Read(char[], int, int) अधिभार (जो लंबाई को सीमित करता है) का उपयोग करना होगा और अपना स्वयं का अंत-पता लगाने का उपयोग करना होगा; बहुत मुश्किल नहीं होना चाहिए।

एक से थोड़ा आलसी संस्करण के लिए

(एकल-characted पढ़ने संस्करण का उपयोग करता):

static IEnumerable<string> ReadLines(string path, int maxLineLength) 
{ 
    StringBuilder currentLine = new StringBuilder(maxLineLength); 
    using (var reader = File.OpenText(path)) 
    { 
     int i; 
     while((i = reader.Read()) > 0) { 
      char c = (char) i; 
      if(c == '\r' || c == '\n') { 
       yield return currentLine.ToString(); 
       currentLine.Length = 0; 
       continue; 
      } 
      currentLine.Append((char)c); 
      if (currentLine.Length > maxLineLength) 
      { 
       throw new InvalidOperationException("Max length exceeded"); 
      } 
     } 
     if (currentLine.Length > 0) 
     { 
      yield return currentLine.ToString(); 
     }     
    } 
} 
4

आप StreamReader.Read अधिभार में से एक की जरूरत हो सकती:

sr.Read(c, 0, c.Length) लाइन पर से http://msdn.microsoft.com/en-us/library/9kstw824.aspx

using (StreamReader sr = new StreamReader(path)) 
    { 
     //This is an arbitrary size for this example. 
     char[] c = null; 

     while (sr.Peek() >= 0) 
     { 
      c = new char[5]; 
      sr.Read(c, 0, c.Length); 
      //The output will look odd, because 
      //only five characters are read at a time. 
      Console.WriteLine(c); 
     } 
    } 

फोकस लिया। यह स्ट्रीम से केवल 5 वर्ण पढ़ता है और c सरणी में डाल देता है। आप इच्छित मूल्य में 5 बदलना चाह सकते हैं।

using System; 
using System.IO; 
using System.Text; 

namespace MyProject 
{ 
    class StreamReaderExt : StreamReader 
    { 

     public StreamReaderExt(Stream s, Encoding e) : base(s, e) 
     {    
     } 

     /// <summary> 
     /// Reads a line of characters terminated by CR+LF from the current stream and returns the data as a string 
     /// </summary> 
     /// <param name="maxLineLength">Maximum allowed line length</param> 
     /// <exception cref="System.IO.IOException" /> 
     /// <exception cref="System.InvalidOperationException">When string read by this method exceeds the maximum allowed line length</exception> 
     /// <returns></returns> 
     public string ReadLineCRLF(int maxLineLength) 
     { 
      StringBuilder currentLine = new StringBuilder(maxLineLength); 

      int i; 
      bool foundCR = false; 
      bool readData = false; 

      while ((i = Read()) > 0) 
      { 

       readData = true; 

       char c = (char)i; 

       if (foundCR) 
       { 
        if (c == '\r') 
        { 
         // If CR was found before , and the next character is also CR, 
         // adding previously skipped CR to the result string 
         currentLine.Append('\r'); 
         continue; 
        } 
        else if (c == '\n') 
        { 
         // LF found, finished reading the string 
         return currentLine.ToString(); 
        } 
        else 
        { 
         // If CR was found before , but the next character is not LF, 
         // adding previously skipped CR to the result string 
         currentLine.Append('\r'); 
         foundCR = false; 
        } 
       } 
       else // CR not found 
       { 
        if (c == '\r') 
        { 
         foundCR = true; 
         continue; 
        } 
       } 

       currentLine.Append((char)c); 
       if (currentLine.Length > maxLineLength) 
       { 
        throw new InvalidOperationException("Max line length exceeded"); 
       } 
      } 

      if (foundCR) 
      { 
       // If CR was found before, and the end of the stream has been reached, appending the skipped CR character 
       currentLine.Append('\r'); 
      } 

      if (readData) 
      { 
       return currentLine.ToString(); 
      } 

      // End of the stream reached 
      return null; 

     } 
    } 
} 

कोड का यह टुकड़ा प्रदान की जाती है कोई वारंटी के साथ "जैसा है":

2

यहाँ अपने खुद के समाधान मार्क Gravell द्वारा समाधान पर आधारित है।

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