Frage

Ich bin eine Web-Server-Anwendung in C # zu schreiben und mit Klasse Stream von einem darunter liegenden Network zu lesen:

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

Dieser Code ist anfällig für DoS-Angriffe, weil, wenn der Angreifer trennt nie werden wir nie die Linie zu lesen beenden. Gibt es eine Möglichkeit, die Anzahl der Zeichen von StreamReader.ReadLine () in .NET lesen zu begrenzen?

War es hilfreich?

Lösung

würden Sie haben die Read(char[], int, int) Überlastung verwenden (die die Länge beschränkt) und tun Sie Ihre eigene End-of-line-Erkennung; sollte nicht zu schwierig sein.

Für eine etwas faul Version (das verwendet die Single-characted Leseversion):

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();
        }                
    }
}

Andere Tipps

Sie müssen möglicherweise eine der StreamReader.Read Überlastung:

Genommen von 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);
        }
    }

Fokus auf der sr.Read(c, 0, c.Length) Linie. Diese liest nur 5 Zeichen aus dem Strom und in in c Array gesetzt. Sie wollen, können Sie 5 Wert geändert werden soll.

Hier ist meine eigene Lösung basiert auf der Lösung von Marc GRA:

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;

        }
    }
}

Dieses Stück Code wird "AS IS" ohne Garantie.

Sie können immer ".Read (...)" verwenden und MSDN empfiehlt wie das Ihre tun, um für eine Situation.

http://msdn.microsoft.com/en-us/library/system .io.streamreader.readline.aspx

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top