我正在尝试创建一个可以处理非常大的请求的 HTTP 服务器。为了避免高内存使用,我认为以块的形式读取连接流是最好的选择。
问题是读取
BufferedReader
会锁定,直到读取到 128 个字节。当流关闭时,它最终读取缓冲区并工作。
如何读取当前存储的数据而不是等待缓冲区填满?
我的代码:
const BUFFER_SIZE = 128;
fn process_chunk(chunk: []u8, size: usize) bool{
std.log.debug("Readed size: {d}", .{size});
if(std.mem.containsAtLeast(u8, "\r\n", 1, chunk) or size < 128){
return true;
}
return false;
}
fn handleConnection( connection: std.net.Server.Connection) !void{
var buffer: [BUFFER_SIZE]u8 = undefined;
const stream_reader = connection.stream.reader().any();
var reader = std.io.BufferedReader(128, @TypeOf(rr)){.unbuffered_reader = stream_reader};
while (true) {
const bbis = try reader.read(&buffer);
std.log.debug("Readed size: {d}", .{bbis});
if(process_chunk(&buffer)){
connection.stream.close();
return;
}
}
}
完整输出:
debug: Readed size: 128
debug: Readed size: 128
debug: Readed size: 128
debug: Readed size: 128
debug: Readed size: 128
debug: Readed size: 128
debug: Readed size: 128
debug: Readed size: 128
将
[128]u8
传递给 .read()
基本上是说您要等到 128 个字节可用或直到流结束。
我建议根据您正在实施的协议,阅读任何有用的数据量。 例如,如果您正在读取 64 位整数流,您将按 8 个块读取(或者更好,
readInt(u64, ...)
)。
分块带来的实际性能提升将由 BufferedReader 处理,因此您的代码应该只关心下一步处理可以处理多少字节。 下一个字符或标记、一些前瞻字节数、下一个字段等。
readUntilDelimiter
函数类在这里可能会很好。