You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
teamwk123/users/xuchen/client.py

97 lines
2.3 KiB

#coding=utf8
'''
客户端 udp协议 方法:
1.通过多线程实现停等协议来进行可靠传输,
2.通过压缩、分块实现文件的快速重传
3.服务端接收后进行解压缩操作
'''
import socket
import os
import hashlib
from os.path import basename
from threading import Thread,Event
from time import sleep
import zipfile
import gzip
#-------------------------------配置--------------------------------------------
#------------------------------config--------------------------------------------
ip='192.168.230.141'#server的ip
port=7777 #server的port
BUFFER_SIZE= 4*1024*1024 #4G进行分块处理
dst='file.txt' #目的文件夹
port_ack=7778 #发送给server端ack消息的端口
fn_path='output.bin'
fn_path_zip=fn_path+".gz"
ack_address=(ip,port_ack)
#------------------------------大文件压缩-------------------------------------------
BufSize = 1024*16
def gZipFile(src, dst):
fin = open(src, 'rb')
fout = gzip.open(dst, 'wb')
in2out(fin, fout)
def gunZipFile(gzFile, dst):
fin = gzip.open(gzFile, 'rb')
fout = open(dst, 'wb')
in2out(fin, fout)
def in2out(fin, fout):
while True:
buf = fin.read(BufSize)
if len(buf) < 1:
break
fout.write(buf)
fin.close()
fout.close() #关闭文件
#------------------------------中间文件-------------------------------------------
#用来临时保存数据
data=set()
#接收数据的socket
sock_recv=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
sock_recv.bind(('',port))
#确认反馈地址
sock_ack=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
#重复收包次数
repeat=0
while True:
buffer,_=sock_recv.recvfrom(BUFFER_SIZE)
#全部接收完成,获取文件名
if buffer.startswith(b'over_'):
fn=buffer[5:].decode()
#多确认几次文件传输结束,防止发送方丢包收不到确认
for i in range(5):
sock_ack.sendto(fn.encode()+b'_ack',ack_address)
break
buffer=tuple(buffer.split(b'_',maxsplit=1))
if buffer in data:
repeat=repeat+1
else:
data.add(buffer)
sock_ack.sendto(buffer[0]+b'_ack',ack_address)
sock_recv.close()
sock_ack.close()
data=sorted(data,key=lambda item:int(item[0]))
with open(fn,'wb') as fp:
for item in data:
fp.write(item[1])
#gunZipFile(fn_path_zip,dst)