基于多线程的TCP/IP多客户端双向通信服务器与客户端实现
实现支持多线程、多客户端的TCP双向通信服务
我正在尝试创建支持多线程、多客户端的TCP/IP双向通信服务器与客户端,允许多个客户端连接并进行双向数据收发。需要说明的是,这并非广播消息的聊天服务器,而是可与指定连接客户端单独收发数据的服务:服务器收到客户端请求后可发送数据,也可主动向客户端请求数据以获取响应。
我已尝试实现该功能,以下是client.rs、server.rs和main.rs的代码:
client.rs
// client.rs use std::io::{Read, Write}; use std::net::TcpStream; use std::thread; pub fn run() { let mut stream = TcpStream::connect("127.0.0.1:8080").expect("Failed to connect to server"); let mut cloned_stream = stream.try_clone().expect("Failed to clone stream"); thread::spawn(move || { let mut buffer = [0; 1024]; loop { let bytes_read = cloned_stream .read(&mut buffer) .expect("Failed to read from server"); if bytes_read == 0 { println!("Server disconnected"); return; } println!( "Received from server: {}", String::from_utf8_lossy(&buffer[..bytes_read]) ); } }); loop { let mut input = String::new(); std::io::stdin() .read_line(&mut input) .expect("Failed to read input"); stream .write_all(input.as_bytes()) .expect("Failed to write to server"); } }
server.rs
// server.rs use std::io::{Read, Write}; use std::net::{TcpListener, TcpStream}; use std::thread; pub fn run() { let listener = TcpListener::bind("127.0.0.1:8080").expect("Failed to bind"); println!("Server listening on port 8080..."); for stream in listener.incoming() { match stream { Ok(stream) => { thread::spawn(move || { handle_client(stream); }); } Err(e) => { println!("Failed to accept connection: {:?}", e); } } } } fn handle_client(mut stream: TcpStream) { println!("Client connected: {:?}", stream.peer_addr().unwrap()); let mut buffer = [0; 1024]; loop { match stream.read(&mut buffer) { Ok(bytes_read) => { if bytes_read == 0 { println!("Client disconnected: {:?}", stream.peer_addr().unwrap()); return; } println!( "Received: {}", String::from_utf8_lossy(&buffer[..bytes_read]) ); // Echo back to the client stream.write_all(&buffer[..bytes_read]).unwrap(); } Err(_) => { println!( "Error reading from client: {:?}", stream.peer_addr().unwrap() ); return; } } } }
main.rs
use std::env; mod client; mod server; fn main() { let args: Vec<String> = env::args().collect(); if args.len() != 2 { println!("Usage: {} [server|client]", args[0]); return; } let mode = &args[1]; match mode.as_str() { "server" => { println!("Starting server..."); server::run(); } "client" => { println!("Starting client..."); client::run(); } _ => { println!("Invalid mode. Please specify either 'server' or 'client'."); } } }
内容的提问来源于stack exchange,提问作者i_am_learning
相关产品推荐
相关产品推荐

