一个《简单》的局域网内文件互传小程序

已经用py实现了一个,code如下;

import socket
import sys
import os
import threading
def recvfile():
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

    s.bind(("0.0.0.0",2333))
    s.listen()
    def deal(sock,addr):
        data=sock.recv(50)
        sock.send(data)
        filename = data.decode().replace(" ","")
        print("{}_{}".format(addr,filename))
        
        with open("{}_{}".format(addr,filename),"wb") as f:
            data=sock.recv(2048)
            while data:
                # print(data)
                f.write(data)
                data=sock.recv(2048)
        print("接收完成:{}_{}".format(addr,filename))

    while True:
        sock,addr = s.accept()
        threading.Thread(target=deal,args=(sock,addr,)).start()

def sendfile(ip:str):
    
    cc = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    try:
        cc.connect((ip,2333))
        filesize = os.path.getsize(sys.argv[1])
        filename = os.path.basename(sys.argv[1])
        filesize_couunt = filesize//2048
        print("{}:{}字节".format(filename,filesize))
        with open(sys.argv[1],"rb") as f:
            filename=filename+" "*(50-len(filename))
            cc.send(filename.encode())
            data = cc.recv(50)
            if data == filename.encode():
                data=f.read(2048)
                # print(data)
                count=0
                count_p_idx=0
                while data!=b'':
                    cc.send(data)
                    count+=1
                    
                    if (10*count//filesize_couunt)>count_p_idx and (10*count//filesize_couunt)%2==0:
                        count_p_idx = (10*count//filesize_couunt)
                        print("传输进度:{:.2f}%...".format(count*100/filesize_couunt),end="\r")
                    data=f.read(2048)
                cc.close()
                print("\n发送完成 cli")
            else:
                cc.close()
    except:
        pass
if __name__=="__main__":
    if len(sys.argv) ==1:
        recvfile()
    else:
        for idx in [1,2,3]:
            for idy in range(1,254):
                threading.Thread(target=sendfile,args=("10.238.{}.{}".format(idx,idy),)).start()

这个程序打包成exe 双击运行为接收端,拖动文件到exe上即可发送程序;通过变量局域网内的ip和简单的服务验证进行文件发送;

现用rust重构,发现发送文件发不全,貌似是因为主进程或者借用变量被释放的原因,子线程还没把文件发送完成就被强制退出了;

use std::io::prelude::*;
use std::net::TcpStream;

use std::env;
use std::path::Path;
use std::thread;
fn sendfile(ip:&str,file_path:&str,file_name:&str) ->std::io::Result<()>{
    let mut stream = TcpStream::connect(ip)?;

    let mut filename = [32;50];
    let mut filename_get = [0;50];
    filename[..file_name.len()].copy_from_slice(file_name.as_bytes());
    stream.write(&filename)?;
    stream.read(&mut filename_get)?;
    if filename_get==filename{
        let mut sendbuff = [0;2048];
        // println!("{:?}",buff);
        let mut f= std::fs::File::open(file_path).unwrap();
        let mut n=0;
        n=f.read(&mut sendbuff).unwrap();
        while n>0 {
            stream.write(&sendbuff[..n])?;
            n=f.read(&mut sendbuff).unwrap();
        }
    }
    
    Ok(())
}
fn main() -> std::io::Result<()> {
    let args_all:Vec<String> = env::args().collect();
    if args_all.len()>1{
        // println!("{}",&args_all[1]);
        // let agv1 = args_all[1].clone();
        // let path=Path::new(&agv1);
        // let filepath = &args_all[1];
        // println!("filename:{}",path.file_name().unwrap().to_str().unwrap());
        // let filename = path.file_name().unwrap().to_str().unwrap();
        let mut thread_vec : Vec<thread::JoinHandle<()>> = Vec::new();
        for idx in 1..4{
            for idy in 1..255 {
                
                
                let thread_join_handle=thread::spawn(move || {
                    let args_all_1:Vec<String> = env::args().collect();
                    let filepath = args_all_1[1].clone(); 
                    // let filepath_str = filepath.as_str().clone();
                    let filename = Path::new(&filepath).file_name().unwrap().to_str().unwrap().clone();
                    let ip_format = format!("10.238.{}.{}:2333",idx,idy);
                    println!("{}",ip_format);
                    sendfile(&ip_format, &filepath, &filename).unwrap();
                });
                
                thread_vec.push(thread_join_handle);
                
            }

        }
        for handle in thread_vec{
            handle.join().unwrap();
        }

        // sendfile("10.238.0.0:2333", &args_all[1], &path.file_name().unwrap().to_str().unwrap())?;
    }else{
        println!("len not enght");
    }
    
    // sendfile("0,0,0,0:2333")?;
    Ok(())
} // the stream is closed here

在所有权和声明周期与编译器斗智斗勇的结果;

tcp·rust·python
261 views
Comments
登录后评论
Sign In
·

能发一个报错信息看看吗

·

强啊