parent
d6362e39fd
commit
d0473821b0
@ -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'))
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in new issue