如何断开我的简单 tcp 服务器中的连接?
How do I drop the connection in my simple tcp server?
我用 tcp 举了一个非常简单的 rust 服务器示例。
use std::net::{Shutdown,TcpListener, TcpStream};
use std::thread;
use std::io::{Read,Write,Error};
fn handle_client(mut stream: TcpStream)-> Result<(), Error> {
println!("incoming connection from: {}", stream.peer_addr()?);
let mut buf = [0;512];
loop {
let bytes_read = stream.read(&mut buf)?;
if bytes_read == 0 {return Ok(())}
let tmp = format!("{}", String::from_utf8_lossy(&buf).trim());
eprintln!("getting {}",tmp);
stream.write(&buf[..bytes_read])?;
}
}
fn main() {
let listener = TcpListener::bind("0.0.0.0:8888").expect("Could not bind");
for stream in listener.incoming() {
match stream {
Err(e)=> {eprintln!("failed: {}", e)}
Ok(stream) => {
thread::spawn(move || {
handle_client(stream).unwrap_or_else(|error| eprintln!("{:?}", error));
});
}
}
}
}
它基本上接受输入,将其吐回客户端,然后打印到它自己的终端。
我希望能够结束此连接。结束连接应该取决于某些事情,但现在我只想尝试关闭它。
我尝试查看文档,然后尝试添加 shutdown
方法
现在,我想将一些流作为输入,对其进行处理,然后关闭频道
所以我尝试这样做:
fn main() {
let listener = TcpListener::bind("0.0.0.0:8888").expect("Could not bind");
for stream in listener.incoming() {
match stream {
Err(e)=> {eprintln!("failed: {}", e)}
Ok(stream) => {
thread::spawn(move || {
handle_client(stream).unwrap_or_else(|error| eprintln!("{:?}", error));
});
stream.shutdown(Shutdown::Both).expect("shutdown call failed");
}
}
}
}
但这会导致 "stream"
成为移动值的问题。
那么如何在接收到输入并对其进行处理后立即关闭频道?
(我还是想用循环保留这个结构,因为我其实想接收很多消息,然后根据输入关闭)
您可以尝试克隆流并将该流克隆传递给您生成的函数。然后,您可以在处理完客户端后在生成的函数中调用关闭。
这样,您的原始 stream 变量将保持不变,您可以拥有您想要的行为。
您遇到此问题的原因是生成的函数由于 move 关键字而移动它捕获的所有内容。
fn main() {
let listener = TcpListener::bind("0.0.0.0:8888").expect("Could not bind");
for stream in listener.incoming() {
let stream_clone = stream.clone();
match stream {
Err(e)=> {eprintln!("failed: {}", e)}
Ok(stream) => {
thread::spawn(move || {
handle_client(stream_clone).unwrap_or_else(|error| eprintln!("{:?}", error));
stream_clone.shutdown(Shutdown::Both).expect("shutdown call failed");
});
}
}
}
}
此外,您需要将句柄客户端的签名更改为 fn handle_client(stream: &mut TcpStream)-> Result<(), Error> 所以它也不会移动克隆的流变量,而是作为可变变量钻入。
我用 tcp 举了一个非常简单的 rust 服务器示例。
use std::net::{Shutdown,TcpListener, TcpStream};
use std::thread;
use std::io::{Read,Write,Error};
fn handle_client(mut stream: TcpStream)-> Result<(), Error> {
println!("incoming connection from: {}", stream.peer_addr()?);
let mut buf = [0;512];
loop {
let bytes_read = stream.read(&mut buf)?;
if bytes_read == 0 {return Ok(())}
let tmp = format!("{}", String::from_utf8_lossy(&buf).trim());
eprintln!("getting {}",tmp);
stream.write(&buf[..bytes_read])?;
}
}
fn main() {
let listener = TcpListener::bind("0.0.0.0:8888").expect("Could not bind");
for stream in listener.incoming() {
match stream {
Err(e)=> {eprintln!("failed: {}", e)}
Ok(stream) => {
thread::spawn(move || {
handle_client(stream).unwrap_or_else(|error| eprintln!("{:?}", error));
});
}
}
}
}
它基本上接受输入,将其吐回客户端,然后打印到它自己的终端。
我希望能够结束此连接。结束连接应该取决于某些事情,但现在我只想尝试关闭它。
我尝试查看文档,然后尝试添加 shutdown
方法
现在,我想将一些流作为输入,对其进行处理,然后关闭频道
所以我尝试这样做:
fn main() {
let listener = TcpListener::bind("0.0.0.0:8888").expect("Could not bind");
for stream in listener.incoming() {
match stream {
Err(e)=> {eprintln!("failed: {}", e)}
Ok(stream) => {
thread::spawn(move || {
handle_client(stream).unwrap_or_else(|error| eprintln!("{:?}", error));
});
stream.shutdown(Shutdown::Both).expect("shutdown call failed");
}
}
}
}
但这会导致 "stream"
成为移动值的问题。
那么如何在接收到输入并对其进行处理后立即关闭频道?
(我还是想用循环保留这个结构,因为我其实想接收很多消息,然后根据输入关闭)
您可以尝试克隆流并将该流克隆传递给您生成的函数。然后,您可以在处理完客户端后在生成的函数中调用关闭。
这样,您的原始 stream 变量将保持不变,您可以拥有您想要的行为。
您遇到此问题的原因是生成的函数由于 move 关键字而移动它捕获的所有内容。
fn main() {
let listener = TcpListener::bind("0.0.0.0:8888").expect("Could not bind");
for stream in listener.incoming() {
let stream_clone = stream.clone();
match stream {
Err(e)=> {eprintln!("failed: {}", e)}
Ok(stream) => {
thread::spawn(move || {
handle_client(stream_clone).unwrap_or_else(|error| eprintln!("{:?}", error));
stream_clone.shutdown(Shutdown::Both).expect("shutdown call failed");
});
}
}
}
}
此外,您需要将句柄客户端的签名更改为 fn handle_client(stream: &mut TcpStream)-> Result<(), Error> 所以它也不会移动克隆的流变量,而是作为可变变量钻入。