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()