.NET에서 streamReader.Readline ()에서 읽는 문자 수를 제한하는 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/400407

문제

C#에서 웹 서버 응용 프로그램을 작성하고 StreamReader 클래스를 사용하여 기본 네트워크 스트림에서 읽습니다.

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

이 코드는 공격자가 연결을 끊지 않으면 라인을 읽지 않기 때문에 DOS 공격이 발생하기 쉽습니다. .NET에서 streamReader.Readline ()이 읽는 문자 수를 제한하는 방법이 있습니까?

도움이 되었습니까?

해결책

당신은 그것을 사용해야 할 것입니다 Read(char[], int, int) 오버로드 (길이를 제한)하고 자신의 라인 끝 감지를 수행합니다. 너무 까다로워서는 안됩니다.

약간 게으른 버전의 경우 (단일 차가 판독 버전을 사용하는) :

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

다른 팁

하나가 필요할 수 있습니다 StreamReader.Read 초과 적재:

가져 왔습니다 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);
        }
    }

초점 sr.Read(c, 0, c.Length) 선. 이것은 스트림에서 5 자만 읽고 c 정렬. 원하는 가치로 5를 변경하고 싶을 수도 있습니다.

다음은 Marc Gravell의 솔루션을 기반으로 한 내 솔루션입니다.

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;

        }
    }
}

이 코드는 보증이없는 "그대로"제공됩니다.

항상 ".read (...)"를 사용할 수 있으며 MSDN은 귀하와 같은 상황에 대해 그렇게하는 것이 좋습니다.

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

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top