已经用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
在所有权和声明周期与编译器斗智斗勇的结果;