【发布时间】:2016-01-26 10:28:05
【问题描述】:
我正在尝试用 Rust 编写一个极其简单的并发服务器,以使用该语言的并发原语及其线程模型。这是我的代码:
use std::io::prelude::*;
use std::io::Result;
use std::net::{TcpListener, TcpStream, Shutdown};
use std::sync::{Arc, Mutex};
use std::thread;
fn handle_client(mut stream: TcpStream) -> Result<()> {
try!(stream.write(b"HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\nContent-Length: 5\r\n\r\nPong!\r\n"));
// try!(stream.shutdown(Shutdown::Both));
Ok(())
}
fn main() {
let listener = TcpListener::bind("127.0.0.1:1337").unwrap();
// let count = Arc::new(Mutex::new(0));
for stream in listener.incoming() {
match stream {
Ok(stream) => {
// let count = count.clone();
thread::spawn(move || {
let _ = handle_client(stream);
// let mut count = count.lock().unwrap();
// *count += 1;
// println!("{:?}", *count);
});
}
Err(e) => {
println!("Error: {}", e);
}
}
}
drop(listener);
}
当我在上面列出的程序运行的情况下运行ab -c 100 -n 100 http://127.0.0.1:1337/ 时,我几乎立即得到apr_socket_recv: Connection reset by peer (104)。为什么?
当我添加 try!(stream.shutdown(Shutdown::Both));(在上面的顶部附近注释掉)时,我不再像以前那样收到 apr_socket_recv 错误,但是 apachebench 给我的结果是 199 个由于异常而失败的请求。为什么?我做错了什么?
Concurrency Level: 100
Time taken for tests: 0.008 seconds
Complete requests: 100
Failed requests: 199
(Connect: 0, Receive: 0, Length: 0, Exceptions: 199)
Total transferred: 500 bytes
【问题讨论】:
-
顺便说一句,您的内容长度不是 5,而是 7(您错过了最后一个 \r\n)。但我认为这不太可能是错误的原因......
-
您可以尝试在详细模式下运行它吗(在命令行中添加
-v标志)?奇怪的是 2/3 的请求都失败了……如果它们都失败了,我会理解的…… -
我建议不要使用
use std::io::Result,因为这会影响“正常”Result类型。我建议改为use std::io和io::Result。此外,很少需要明确使用drop。值将在定义它们的范围结束时自动删除。 -
您还应该在提问时创建一个MCVE。例如,this version 使用 no threading 但在使用
ab -c 1 -n 5000运行时会出现同样的问题。 -
此外,cURL 偶尔会报告相同的“连接重置”错误,因此它与 apachebench 无关。
标签: multithreading http server rust apachebench