python socket粘包

1.在linux中经常出现粘包的出现(因为两个send近靠着,造成接受到的数据是在一起的。)解决方法:

在服务端两send的中间中再添加一个recv(),客户端添加一个send(),服务端收到信息确认客户端已经收到第一个send发送的信息后,再发送第二个send中的内容。

2.需求: 客户端向linux服务端传送get指令,将服务端get到的数据传送到客户端,通过md5 验证传送后的数据是否正确,最后一次数据剩多少传输多少,防止数据粘包。

#coding:utf-8
'''客户端'''
import socket
import hashlib

client = socket.socket()

client.connect(('192.168.121.129', 9999))

while True:
    cmd = input(">>:").strip()
    if len(cmd) == 0: continue
    if cmd.startswith("get"):
        client.send(cmd.encode())
        server_response = client.recv(1024)
        print("servr response:", server_response)
        client.send(b"ready to recv file")
        file_total_size = int(server_response.decode())
        received_size = 0
        filename = cmd.split()[1]
        f = open(filename + ".new", "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(size)
            received_size += len(data)
            m.update(data)
            f.write(data)
            # print(file_total_size,received_size)
        else:
            new_file_md5 = m.hexdigest()
            print("file recv 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()
#coding:utf-8
'''服务端'''
import hashlib
import socket ,os,time
server = socket.socket()
server.bind(('0.0.0.0',9999) )
server.listen(5)
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
           conn.send( str(file_size).encode() ) #send file size
           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("send done")

server.close()

猜你喜欢

转载自www.cnblogs.com/iexperience/p/9257998.html