socket实现简单的文件下载传输功能

server: 

#!/usr/bin/python
#coding:utf-8
import socket,os
import hashlib

server = socket.socket()
#运行再次使用绑定的socket地址(比如客户端异常断开,server端起来报地址已经存在,设置和这个可以强制使用)
server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
server.bind(('localhost',9999))
server.listen(5)

while True:
conn,addr = server.accept() #等待client连接进来
print('new conn:',addr)
while True:
print('等待新指令')
data = conn.recv(1024) #接受client的信息
if not data:
print('客户端没有发送数据,断开了')
break
cmd,filename = data.decode().split()
print(filename)# client --get 文件名字(tetst.txt)
if os.path.isfile(filename):#判断本地目录有这个文件
f = open(filename,'rb')
m = hashlib.md5()#获取md5的实例
file_size = os.stat(filename).st_size #这个是 int 数字。
conn.send(str(file_size).encode('utf-8'))#发送要下载的文件大小字节
conn.recv(1024)#等待接受ack回应
for line in f:
m.update(line)#生成md5
conn.send(line)#发送一行数据给client
print('MD5验证码是:',m.hexdigest())
f.close()
conn.send(m.hexdigest().encode())#发送md5给client
print('发送结束')

server.close()

 

client:

#!/usr/bin/python
#coding:utf-8
import socket,os
import hashlib

client = socket.socket()#声明一个socket类型,同时生成对象
client.connect(('localhost',9999))

while True:
cmd = input('client>>:').strip()#输入下载的get xxx.tt
if len(cmd) == 0:continue #输入空,就重新输入
if cmd.startswith('get'):#cmd开始是 get开头
client.send(cmd.encode('utf-8')) #把文件名发送给server端
server_response = client.recv(1024)#接受要下载的文件总大小
print('要下载文件总大小是:',server_response.decode())
client.send('确认ack,开始接受数据下载'.encode())
file_total_size = int(server_response.decode())#文件大小字符串转成int
recesize = 0
filename = cmd.split()[1]#获取输入的文件名字
print('文件名字是',filename)
f =open(filename+'.new','wb')
m = hashlib.md5()

while recesize < file_total_size: #接受的文件大小小于总大小,就继续接收
if file_total_size - recesize > 1024: #判断最后一次接收
size = 1024
else:#最后一次发送,解决粘包问题(md5)
size = file_total_size - recesize
print('最后一次接收的大小是:',size)
print('传进来的size是:',size)
data = client.recv(size)#接收客户端的数据
recesize += len(data)
print(recesize)
m.update(data)#计算md5
f.write(data)#写入数据到new文件
print('目前接收的原大小和接收的文件大小',file_total_size,recesize)
else:
new_file_md5 = m.hexdigest()#获取接收后的文件md5
print('下载recv 结束')
f.close()
server_file_md5 = client.recv(1024)#接收server端的md5
print(server_file_md5.decode())
print(new_file_md5)

client.close()


posted @ 2020-02-09 10:33  运维魔法师  阅读(1596)  评论(0编辑  收藏  举报