VoiletTftp/src/main.rs
2025-08-09 22:45:15 +08:00

107 lines
3.5 KiB
Rust

#![windows_subsystem = "windows"]
use async_tftp::server::TftpServerBuilder;
use async_tftp::Result;
use rfd::FileDialog;
use slint::SharedString;
use std::path::PathBuf;
use tokio::task::{AbortHandle, JoinHandle};
use std::sync::{Arc, Mutex};
slint::include_modules!();
struct ServerState {
abort_handle: Option<AbortHandle>,
}
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();
let ui_weak = ui.as_weak();
//选择路径按钮的回调函数
ui.on_BrowserFolder(move || {
let result = FileDialog::new()
.set_directory("/")
.pick_folder();
let mut path = result.map(|p| p.to_string_lossy().into_owned())
.unwrap_or_default();
if path == "" {
println!("TFTP Dir Empty !");
if let Some(ui) = ui_weak.upgrade() {
ui.set_StartEnable(false);
}
path = String::from("");
}
else {
if let Some(ui) = ui_weak.upgrade() {
ui.set_StartEnable(true);
}
}
*path_clone.lock().unwrap() = path.clone(); // 存储到变量
SharedString::from(path)
});
//启动按钮的回调函数
let state_clone = state.clone();
let path_clone = Arc::clone(&folder_path);
let ui_weak = ui.as_weak();
ui.on_StartTftp(move || {
let dir = PathBuf::from(&*path_clone.lock().unwrap());
if dir.iter().count() == 0 {
println!("TFTP Dir Empty !");
if let Some(ui) = ui_weak.upgrade() {
ui.set_StartEnable(true);
ui.set_StopEnable(false);
}
}
else {
if let Some(ui) = ui_weak.upgrade() {
ui.set_StartEnable(false);
ui.set_StopEnable(true);
}
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 ui_weak = ui.as_weak();
let state_clone = state.clone();
ui.on_StopTftp(move || {
if let Some(ui) = ui_weak.upgrade() {
ui.set_StartEnable(true);
ui.set_StopEnable(false);
}
if let Some(handle) = state_clone.lock().unwrap().abort_handle.take() {
handle.abort();
println!("Server stopped");
}
});
ui.run().unwrap();
}