diff --git a/Cargo.toml b/Cargo.toml index ee5f4c0..9e61a05 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ version = "1.0.0" edition = "2024" [dependencies] -tokio = "1.47.1" +tokio = { version = "1.47.1", features = ["full"] } async-tftp = "0.3.6" slint = "1.12.1" rfd = "0.15.4" diff --git a/components/Window.slint b/components/Window.slint index c335f8b..20cb447 100644 --- a/components/Window.slint +++ b/components/Window.slint @@ -14,6 +14,7 @@ export component MainWindow inherits Window { callback StartTftp(); //停止回调 callback StopTftp(); + //选择路径按钮 Rectangle { height: 35px; width: 95px; diff --git a/src/main.rs b/src/main.rs index 9c9940f..1b3d25e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,38 +2,75 @@ use async_tftp::server::TftpServerBuilder; use async_tftp::Result; use rfd::FileDialog; use slint::SharedString; -use std::error::Error; -// ?use smol::{prelude::*}; +use std::path::PathBuf; +use tokio::task::{AbortHandle, JoinHandle}; +use std::sync::{Arc, Mutex}; slint::include_modules!(); - -async fn StartTftpServer(Dir: &str) -> Result<()> { - println!("Start Tftp Server Dir With:{Dir}"); - let tftpd = TftpServerBuilder::with_dir_ro(Dir)?.build().await?; - tftpd.serve().await?; - Ok(()) +struct ServerState { + abort_handle: Option, } -fn main() { +async fn start_tftp_server(dir: PathBuf) -> Result<(JoinHandle<()>, AbortHandle)> { + let task = tokio::spawn(async move { + println!("Starting TFTP server at: {:?}", dir); + let tftpd = TftpServerBuilder::with_dir_ro(&dir) + .expect("Failed to create server") + .build() + .await + .expect("Failed to bind socket"); + + if let Err(e) = tftpd.serve().await { + eprintln!("Server error: {}", e); + } + }); + + let abort_handle = task.abort_handle(); + Ok((task, abort_handle)) +} +#[tokio::main] +async fn main() { let ui = MainWindow::new().unwrap(); + let state = Arc::new(Mutex::new(ServerState { abort_handle: None })); + let folder_path = Arc::new(Mutex::new(String::new())); + let path_clone = folder_path.clone(); + //选择路径按钮的回调函数 ui.on_BrowserFolder(move || { let result = FileDialog::new() .set_directory("/") .pick_folder(); - - SharedString::from( - result.map(|p| p.to_string_lossy().into_owned()) - .unwrap_or_default() - ) + let path = result.map(|p| p.to_string_lossy().into_owned()) + .unwrap_or_default(); + *path_clone.lock().unwrap() = path.clone(); // 存储到变量 + SharedString::from(path) }); //启动按钮的回调函数 + let state_clone = state.clone(); + let path_clone = Arc::clone(&folder_path); ui.on_StartTftp(move || { - // smol::spawn(StartTftpServer("C:/Users/anonymous/Desktop/Rust/VoiletTftp/target/release/")).detach(); + // let Dir = PathBuf::from("C:/Users/anonymous/Desktop/Rust/VoiletTftp/target/release"); + let dir = PathBuf::from(&*path_clone.lock().unwrap()); + println!("{:?}",dir); + let state = state_clone.clone(); + tokio::spawn(async move { + match start_tftp_server(dir).await { + Ok((_handle, abort_handle)) => { + println!("Server started"); + // 存储 abort_handle 以便停止 + state.lock().unwrap().abort_handle = Some(abort_handle); + } + Err(e) => eprintln!("Error: {}", e), + } + }); }); //停止按钮的回调函数 + let state_clone = state.clone(); ui.on_StopTftp(move || { + if let Some(handle) = state_clone.lock().unwrap().abort_handle.take() { + handle.abort(); + println!("Server stopped"); + } }); ui.run().unwrap(); -} -//启动一个TFTP服务器帮我改写 \ No newline at end of file +} \ No newline at end of file