녹을 시작하려하고 일부 조각을 함께 넣고 각각 "소켓"이있는 "클라이언트"의 벡터를 포함하는 "서버"인스턴스를 갖기 위해 노력했습니다.녹슬지 않는 구조체 필드가 소켓에 대해 변경 가능
녹이면 소켓 또는 TcpStream이 변경 가능해야하며 주 루프에서 클라이언트 인스턴스화 이후에 범위를 유지하려면 참조를 빌려야한다는 것을 알고 있습니다.
하지만 TcpStream 필드가 Client 구조체에서 변경 될 수 없다는 문제가 있습니다. 그래서 내 접근 방식이 정확한지 잘 모르겠지만, 평생 파라미터 < 'a>를 사용하여이 문제를 해결하려고 노력했지만, "서버"내부의 "클라이언트"가 평생을 <에 전달하지 않는 또 다른 문제가 생깁니다. 매개 변수.
누군가가이 문제를 해결하거나이 문제/솔루션에 대한 올바른 접근 방식을 보여줄 수 있습니까?
감사합니다.
use std::net::*;
use std::io::Write;
use std::thread;
use std::time::Duration;
struct Client<'a> {
socket: &'a mut TcpStream,
addr: SocketAddr
}
struct Server {
clients: Vec<Box<Client>>
}
impl Server {
pub fn new() -> Server {
Server{clients: Vec::new()}
}
fn write(&self, stream: &mut TcpStream) {
let mut counter: u32 = 0;
counter += 1;
stream.write(counter.to_string().as_bytes()).unwrap();
thread::sleep(Duration::from_secs(1));
}
fn client_thread(&self, client: &mut Client) {
self.write(&mut client.socket);
}
fn add_client(&self, socket: &mut TcpStream, addr: SocketAddr) {
let mut client = Client {
socket: socket,
addr: addr
};
self.clients.push(Box::new(client));
self.client_thread(&mut client);
}
pub fn server_loop(&self) {
let listener = TcpListener::bind("127.0.0.1:5001").unwrap();
loop {
match listener.accept() {
Ok((mut socket, addr)) => {
println!("new client: {:?}", addr);
thread::spawn(move || loop {
self.add_client(&mut socket, addr);
});
},
Err(e) => println!("couldn't get client: {:?}", e),
}
}
}
}
fn main() {
let mut server = Server::new();
server.server_loop();
}
업데이트 :
현재 오류 메시지는 다음과 같습니다
clients: Vec<Box<Client>>
^^^^^^ expected lifetime parameter
업데이트 2 :
이 지금은 솔루션이 목표에 가까운/조금 더 나은 생각합니다. 하지만 여전히 스레드에 문제가 있습니다. 정적 컨텍스트 외부에 생성하십시오.
use std::net::*;
use std::io::Write;
use std::thread;
struct Client {
socket: TcpStream
}
struct Server {
clients: Vec<Box<Client>>
}
impl Server {
fn new() -> Server {
Server{clients: vec![]}
}
fn write(&mut self, stream: &mut TcpStream) {
let mut counter: u32 = 0;
stream.write(counter.to_string().as_bytes()).unwrap();
}
fn client_loop(&mut self, client: &mut Client) {
loop {
self.write(&mut client.socket);
}
}
fn add_client(&mut self, s: TcpStream) {
let mut client = Client{
socket: s
};
self.clients.push(Box::new(client));
println!("New client: {}", client.socket.peer_addr().unwrap());
thread::spawn(move || {
self.client_loop(&mut client);
});
}
pub fn server_loop(&mut self) {
let listener = TcpListener::bind("127.0.0.1:5001").unwrap();
loop {
match listener.accept() {
Ok((socket, _addr)) => {
self.add_client(socket);
},
Err(e) => println!("Couldn't get client: {}", e),
}
}
}
}
fn main() {
let mut server = Server::new();
server.server_loop();
}
오류 [E0477] : 유형 [[email protected]/main.rs:38:23: 40:10 self:&mut Server, client:Client]
필요한 수명을 충족하지 않는
--> src/main.rs:38:9
|
38 | thread::spawn(move || {
| ^^^^^^^^^^^^^
|
= note: type must satisfy the static lifetime
에 대한보다 구체적인주십시오 당신의 발행물. 좋은 [MCVE]는 일반적으로 컴파일러에서 그대로 복사 된 오류 메시지를 포함합니다. –
뻔뻔스럽게도이 코드에는 * 많은 * 문제가 있습니다. 예를 들면 : 당신이 뭔가를 이동 한 후에 참조를 취하고, 로컬 변수에 대한 참조를 쓰레드에 전달하려한다면, 아마도 많은 장소에서'& self' 대신에'mut mut'를 원할 것입니다. [* The Rust Programming Language *] (https://doc.rust-lang.org/book/secondedition/)를 읽으셨습니까? 적극 추천합니다. 그 수명이하는 일이 아니다 - * 나는이 수명 매개 변수'<'a>'*을 사용하여 해결하기 위해 노력했다. 다시,이 책은 수명이 무엇인지 설명 할 것입니다. 격렬하게 대충 빠져서 녹을 배우는 것이 쉽지 않거나 재미 있지 않습니다. – Shepmaster
안녕하세요 @ E_net4, 더 자세한 정보를 제공하지 않아 죄송합니다. 지금 오류 메시지가 추가됩니다. –