From d0473821b056aa37d4ea1d27e3053ac4316c6a73 Mon Sep 17 00:00:00 2001 From: pewxvf3lf <431321064@qq.com> Date: Thu, 26 Dec 2024 23:46:59 +0800 Subject: [PATCH] ADD file via upload --- tcp_client.py | 145 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 tcp_client.py diff --git a/tcp_client.py b/tcp_client.py new file mode 100644 index 0000000..e2c023c --- /dev/null +++ b/tcp_client.py @@ -0,0 +1,145 @@ +from socket import * +import struct +import json +from RSA_Module import * +from Zip_Module import * +from AES import AESdecrypt +from PyQt5.QtCore import pyqtSignal, QObject + +class TCPClient(QObject): + # 定义自定义信号 + + list_received = pyqtSignal(str) + receive_status = pyqtSignal(str) # 当发生错误时发出或者一些状态文件 + receive_progress = pyqtSignal(int) + def __init__(self, buffsize=1024): + super().__init__() + self.buffsize = buffsize + self.tcp_client = socket(AF_INET, SOCK_STREAM) + self.connected = False + def connect(self, ip, port): + self.tcp_client.connect_ex((ip, port)) + self.connected = True + generate_rsakey('clientpub.pem', 'clientpri.pem') + return self.tcp_client + def send_clientpub(self, client_conn): + filesize = os.path.getsize('./.tempfile/clientpub.pem') + newfilename = 'new_' + os.path.basename('./.tempfile/clientpub.pem') + dirc = { + 'filename': newfilename, + 'filesize': filesize, + } + head_info = json.dumps(dirc) + head_info_len = struct.pack('i', len(head_info)) + client_conn.send(head_info_len)#发送head_info的长度 + client_conn.send(head_info.encode('utf-8')) + + #发送文件数据 + with open('./.tempfile/clientpub.pem', 'rb') as f: + data = f.read() + client_conn.sendall(data) + + + def recv_serverpub(self, client_conn): + head_info_len = client_conn.recv(4) + head_info_len = struct.unpack('i',head_info_len)[0] + + #接收并解析报头内容 + head_info = client_conn.recv(head_info_len) + dirc = json.loads(head_info.decode('utf-8')) + filename = dirc['filename'] + filesize = dirc['filesize'] + received_size = 0 + with open(f'./.tempfile/{filename}', 'wb') as f: + while received_size < filesize: + if filesize - received_size > self.buffsize: + data = client_conn.recv(self.buffsize) + f.write(data) + received_size += len(data) + else: + data = client_conn.recv(filesize - received_size) + f.write(data) + received_size += len(data) + if received_size == filesize: + return True, filename + else: + return False, filename + + def receive(self, client_conn): + if not client_conn: + self.receive_status.emit("未连接到服务端") + return + try: + i = 1 + while True: + head_info_len = client_conn.recv(4) + if head_info_len == 4: + self.receive_status.emit('正在接收文件中...') + head_info_len = struct.unpack('i', head_info_len)[0] + + # 接收并解析报头内容 + head_info = client_conn.recv(head_info_len) + dirc = json.loads(head_info.decode('utf-8')) + filename = dirc['filename'] + filesize_bytes = dirc['filesize_bytes'] + fileindex = dirc['fileindex'] + ext = dirc['fileext'] + lineEdit1 = '正在接收第' + str(i) + \ + '号文件【' + filename + '】......' + self.list_received.emit(lineEdit1) + received_size = 0 + with open(f'./.tempfile/{filename}', 'wb') as f: + while received_size < filesize_bytes: + if filesize_bytes - received_size > self.buffsize: + data = client_conn.recv(self.buffsize) + f.write(data) + received_size += len(data) + else: + data = client_conn.recv(filesize_bytes - received_size) + f.write(data) + received_size += len(data) + self.receive_progress.emit(int((received_size / filesize_bytes) * 100)) + lineEdit2 = '成功接收第' + str(i) + \ + '号文件【' + filename + '】 --> ' + \ + os.getcwd() + '\\.tempfile\\' + filename + self.list_received.emit(lineEdit2) + if not self.sign_file(filename, ext): #发送签名状态 + self.send_state(client_conn, i, False) + self.list_received.emit(f'第{i}号文件签名错误,重新接收...') + else: + self.send_state(client_conn, i, True) + self.list_received.emit(f'第{i}号文件签名验证成功') + i = i + 1 + if fileindex == -1: + self.receive_status.emit('文件全部安全接收完成') + break + + except Exception as e: + print(f'接收文件失败: {e}') + return + def sign_file(self, filename, ext): + unzip_file(f'./.tempfile/{filename}', './.tempfile') + aeskey = RSAdecrypt('./.tempfile/clientpri.pem', f'./.tempfile/{filename}_key') + decrypted_message = AESdecrypt(f'./.tempfile/{filename}{ext}', aeskey) + state = verify_signature(decrypted_message,'./.tempfile/new_serverpub.pem',f'./.tempfile/{filename}_sig') + if state: + with open(f'./.tempfile/{filename}{ext}', 'rb') as f : + data = f.read() + with open(f'./{filename}{ext}', 'wb') as s: + s.write(data) + + return state + def send_state(self,client_conn, fileindex, state): + dirc = { + 'fileindex': fileindex, + 'state': state, + } + head_info = json.dumps(dirc) + head_info_len = struct.pack('i', len(head_info)) + + client_conn.send(head_info_len) # 发送head_info的长度 + client_conn.send(head_info.encode('utf-8')) + + + +