Python 3.x--Socket实现简单的ssh和文件下载功能
*****************SSH*********************
---------------服务器端----------------
1 import os,socket 2 3 server = socket.socket() 4 server.bind(('127.0.0.1',6666)) 5 server.listen() 6 7 while True: 8 conn, addr = server.accept() 9 print("new addr:",addr) 10 while True: 11 data = conn.recv(1024) 12 if not data: 13 print("客户端已断开。。。") 14 break 15 print("执行指令。。。",data) 16 res = os.popen(data.decode()).read() #接受命令,并返回结果 17 if len(res)==0: 18 res = "cmd has no output..." 19 conn.send(str(len(res.encode('utf-8'))).encode('utf-8')) #发送输出结果的大小 20 sleep_recv = conn.recv(1024) 21 print("缓冲...",sleep_recv.decode()) #两条send命令可能会出现粘包的情况 22 conn.send(res.encode('utf-8')) 23 24 server.close()
---------------客户端----------------
1 import socket 2 3 client = socket.socket() 4 client.connect(('127.0.0.1',6666)) 5 6 while True: 7 cmd = input(">>>:").strip() 8 if len(cmd)==0: 9 continue 10 client.send(cmd.encode('utf-8')) #发送命令 11 res_size = client.recv(1024) #接收第一个结果:字节长度 12 print("命令结果大小:",res_size) 13 client.send("已准备好接收命令结果。。。".encode("utf-8")) 14 res_size_init = 0 15 res_data = b'' 16 while res_size_init != int(res_size.decode()): 17 data = client.recv(1024) #不一定能接收到正好1024字节的数据 18 print(len(data)) 19 res_size_init += len(data) 20 res_data += data 21 else: 22 print("res_data receive done...",res_size_init) 23 print(res_data.decode()) 24 25 client.close()
运行结果:
---------------服务器端----------------
---------------客户端----------------
*****************文件下载*********************
---------------服务器端----------------
import os,socket,hashlib server = socket.socket() server.bind(('localhost',6666)) server.listen() while True: conn, addr = server.accept() print("new addr:",addr) while True: data = conn.recv(1024) if not data: print("客户端已断开。。。") break cmd, filename = data.decode().split() print(filename) if os.path.isfile(filename): f = open(filename,"rb") m = hashlib.md5() file_size = os.stat(filename).st_size conn.send(str(file_size).encode("utf-8")) #发送文件大小 conn.recv(1024) #等待回复 for line in f: m.update(line) conn.send(line) print("file md5:",m.hexdigest()) f.close() conn.send(m.hexdigest().encode("utf-8")) #发送MD5,与上面的“conn.send(line)”可能出现粘包 print("send done...") server.close()
---------------客户端----------------
import socket,hashlib client = socket.socket() client.connect(('localhost', 6666)) while True: cmd = input(">>>:").strip() if len(cmd)==0: continue if cmd.startswith("get"): filename = cmd.split()[1] #获取文件名 client.send(cmd.encode("utf-8")) server_resp_size = client.recv(1024) #接收文件总的大小 file_total_size = int(server_resp_size.decode()) print("file size:", server_resp_size) client.send(b"ready to recv file...") f = open(filename+".new","wb") recv_size = 0 m = hashlib.md5() while recv_size < file_total_size: if file_total_size - recv_size > 1024: #判断最后一次,之前接收大小设置为1024 size = 1024 else: #最后一次不足1024,则只接收文件剩余的部分,不包含MD5 size = file_total_size - recv_size print("the last size:",size) data = client.recv(size) recv_size += len(data) f.write(data) m.update(data) else: client_md5 = m.hexdigest() print("recv done...") print("total size:", file_total_size, "had been received:", recv_size) server_md5 = client.recv(1024) print("server md5:", client_md5, "server md5:", server_md5.decode()) f.close() client.close()
运行结果: