Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# StreamReader读线内存泄漏_C#_Memory_Tcpclient_Tcplistener - Fatal编程技术网

C# StreamReader读线内存泄漏

C# StreamReader读线内存泄漏,c#,memory,tcpclient,tcplistener,C#,Memory,Tcpclient,Tcplistener,我正在制作一个服务器,我注意到它有一点奇怪的内存泄漏。在我的服务器上,我将一个IP地址可以进行的连接总数限制为8。这很好用 然而,当我使用LOIC来DoS我的服务器时,我注意到虽然它只创建了8个network类实例,但StreamReader的ReadLine方法占用了大量内存 我已经使用Console.WriteLine验证了没有实际接收到数据,它只是在该方法中等待。内存增加并填满了我的整个16GB 需要注意的是,这个类在一个IP上只有8个实例,因为我正在做而不是DDoS,所以它只来自我的I

我正在制作一个服务器,我注意到它有一点奇怪的内存泄漏。在我的服务器上,我将一个IP地址可以进行的连接总数限制为8。这很好用

然而,当我使用LOIC来DoS我的服务器时,我注意到虽然它只创建了8个network类实例,但StreamReader的ReadLine方法占用了大量内存

我已经使用Console.WriteLine验证了没有实际接收到数据,它只是在该方法中等待。内存增加并填满了我的整个16GB

需要注意的是,这个类在一个IP上只有8个实例,因为我正在做而不是DDoS,所以它只来自我的IP(我已经验证了这一点)

此问题的原因是什么?如何解决

编辑:
有关守则如下:

        string data;
        Dictionary<string, string> variables = null;
        try {

            while (_listen) {

                data = null;

                while ((data = _reader.ReadLine()) != null) {
字符串数据;
字典变量=null;
试一试{
边听{
数据=空;
而((数据=_reader.ReadLine())!=null){

函数将把数据缓冲到字符串中,直到遇到
\r\n
\n
单独使用是不行的)。它使用
StringBuilder
。因此,如果您收到的数据不包含序列
\r\n
,它将为单个字符串分配大量内存

这里有一个简单的解决方案:必须限制服务器愿意读取的最大字符串长度。这是处理恶意数据所必需的-如果服务器可能是DoS攻击的受害者,请不要信任您收到的数据

因此,解决方案,作为一种
TextReader
扩展方法:

public static String ReadLineSafe(this TextReader reader, int maxLength)
{ 
    var sb = new StringBuilder();
    while (true) {
        int ch = reader.Read();
        if (ch == -1) break; 
        if (ch == '\r' || ch == '\n')
        { 
            if (ch == '\r' && reader.Peek() == '\n') reader.Read(); 
            return sb.ToString();
        } 
        sb.Append((char)ch);

        // Safety net here
        if (sb.Length > maxLength)
            throw new InvalidOperationException("Line is too long");
    }
    if (sb.Length > 0) return sb.ToString();
    return null; 
}
这是原始的
ReadLine
代码,添加了安全检查


哦,您应该将
网络流
包装在
缓冲流
中进行网络读取,以避免对每个字节调用
recv

如果您不发送换行(
\r\n
)那么,电话线将保持畅通increasing@LucasTrzesniewski我不选择发送什么。这是针对我的服务器运行的DoS攻击。我知道,这只是解释为什么它会消耗内存。我的意思是,如果你关心DoS攻击,你不应该使用
ReadLine
。啊,好的,谢谢。你会推荐什么?我会写的一个anwser。只是一个简单的问题。如果接收的数据长度不可预测怎么办。如果我在描述中有一个用户类型,如果我指定512作为maxLength,它会读取所有2048字节的数据吗?根据您的使用情况,您必须考虑预期接收的数据的合理上限是多少。因为不过,用户不太可能在字段中键入1 MB的文本。然后,添加一些安全裕度并使用它。但是您应该设置的限制是特定于应用程序的。上面的函数读取的字符数不会超过
maxLength
chars。好的,谢谢。我将使用此代码。如果它工作正常,我会将其标记为答案。我尝试了这种方法d、 它不仅使我的电脑速度变慢并填满内存,反而使它崩溃。这可能是由这种方法引起的吗?忽略我以前的评论,这是我的代码中的一个错误,而不是你的。效果很好,这修复了内存泄漏。谢谢