python------Socket网络编程(二)粘包问题

时间:2023-03-08 23:56:53
python------Socket网络编程(二)粘包问题

一.socket网络编程

粘包:服务端两次发送指令在一起,它会把两次发送内容合在一起发送,称为粘包,从而出现错误。

python------Socket网络编程(二)粘包问题

解决方法:(比较low的方法)

python------Socket网络编程(二)粘包问题

有些需要实时更新的,用sleep有延迟,不能这样解决问题。

解决方法之高级方法:

python------Socket网络编程(二)粘包问题

客户端:

python------Socket网络编程(二)粘包问题

二.发送文件

ftp server端有哪几步呢?

①读取客户端发过来的文件名

②检测文件是否存在

③打开文件

④检测文件大小

⑤发送文件大小给客户端

⑥等待客户端确认

⑦开始边读边发数据

⑧发送md5

 import socket
import os
import time
import hashlib
server = socket.socket()
server.bind(('localhost',3333)) server.listen() while True:
conn,addr = server.accept()
print("new conn:",addr)
while True:
print("等待新指令")
data = conn.recv(1024)
if not data:
print("客户端已断开")
break
cmd,filename = data.decode().split()
print(filename)
if os.path.isfile(filename):
f = open(filename,"rb")
m = hashlib.md5()
file_size = os.stat(filename).st_size #在os模块中获取文件大小
conn.send(str(file_size).encode()) #发送文件大小
conn.recv(1024) #wait for ack
for line in f:
m.update(line)
conn.send(line)
print("file md5",m.hexdigest())
f.close()
conn.send(m.hexdigest().encode()) #send md5 print("执行指令:", data) server.close()

客户端:

 import socket
import hashlib
client = socket.socket()
client.connect(('localhost',3333)) while True:
cmd = input(">>:").strip() #cmd = input(b">>:").strip()如果前面直接加b,则只能传英文
if len(cmd) == 0 : continue
if cmd.startswith("get"):
client.send(cmd.encode())
server_response = client.recv(1024)
print("server response:",server_response)
client.send("ready to recv file".encode())
file_total_size = int(server_response.decode())
received_size = 0
filename = cmd.split()[1]
f = open("wenjian","wb")
m = hashlib.md5() while received_size<file_total_size:
#下面这段代码彻底解决粘包问题
if file_total_size - received_size > 1024: #要收不止一次
size = 1024
else:
size = file_total_size - received_size #最后一次了,剩多少收多少
print("last receive:",size) data = client.recv(1024)
received_size += len(data)
m.update(data)
f.write(data)
print(file_total_size,received_size) #看演示效果
else:
new_file_md5 = m.hexdigest()
print("file received done",received_size,file_total_size)
f.close()
server_file_md5 = client.recv(1024)
print("server file md5:",server_file_md5)
print("client file md5:", new_file_md5) client.close()

具体用的时候在钻研吧。