C# StreamReader读线内存泄漏
我正在制作一个服务器,我注意到它有一点奇怪的内存泄漏。在我的服务器上,我将一个IP地址可以进行的连接总数限制为8。这很好用 然而,当我使用LOIC来DoS我的服务器时,我注意到虽然它只创建了8个network类实例,但StreamReader的ReadLine方法占用了大量内存 我已经使用Console.WriteLine验证了没有实际接收到数据,它只是在该方法中等待。内存增加并填满了我的整个16GB 需要注意的是,这个类在一个IP上只有8个实例,因为我正在做而不是DDoS,所以它只来自我的IP(我已经验证了这一点) 此问题的原因是什么?如何解决 编辑: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
有关守则如下:
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、 它不仅使我的电脑速度变慢并填满内存,反而使它崩溃。这可能是由这种方法引起的吗?忽略我以前的评论,这是我的代码中的一个错误,而不是你的。效果很好,这修复了内存泄漏。谢谢