网络编程之粘包解决方案

#解决方案1一收一发

#server.py
import socket
server=socket.socket()
server.bind(('192.168.15.57',8001))
server.listen(3)
while 1:
    print('等待连接。。。')
    conn,addr=server.accept()
    res1=conn.recv(1024).decode('utf-8')
    print('res1:',res1)
    res2=conn.recv(1024).decode('utf-8')
    print('res2:',res2)


#client.py
import socket
client=socket.socket()
client.connect(('192.168.15.57',8001))
client.send('你好呀!!!'.encode('utf-8'))
client.send('我叫赛丽亚^-^'.encode('utf-8'))
while 1:
    pass
client.close()

#解决方案2,先发送长度,在发送数据

#server.py
import socket,subprocess,json
server=socket.socket()
server.bind(('192.168.15.57',8001))
server.listen(3)
while 1:
    print('等待连接。。。')
    conn,addr=server.accept()
    print('连接成功!!!')
    while 1:
        print('等待接受指令。。。')
        from_client_cmd=conn.recv(1024).decode('utf-8')
        print('收到的命令:',from_client_cmd)
        if from_client_cmd.upper()=='Q':
            break
        sub_obj=subprocess.Popen(from_client_cmd,
                                 shell=True,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)
        out=sub_obj.stdout.read()
        err=sub_obj.stderr.read()
        if out:
            conn.send(json.dumps(len(out)).encode('gbk'))
            from_client_res=conn.recv(1024).decode('utf-8')
            if from_client_res :
                conn.send(out)

        elif err:
            conn.send(json.dumps(len(err)).encode('gbk'))
            from_client_res=conn.recv(1024).decode('utf-8')
            if from_client_res:
                conn.send(err)
    print('断开连接。。。')
    conn.close()

#client.py
import socket,json
client=socket.socket()
client.connect(('192.168.15.57',8001))
while 1:
    cmd=input('请输入命令:').replace(' ','')
    client.send(cmd.encode('utf-8'))
    if cmd.upper() == 'Q':
        break
    from_server_msglen=json.loads(client.recv(1024).decode('gbk'))
    print('服务端要发送的数据长度:',from_server_msglen)
    client.send(json.dumps(1).encode('utf-8'))
    from_server_msg=client.recv(from_server_msglen)
    print('接收到的数据长度:',len(from_server_msg))
    print('收到的数据:')
    print(from_server_msg.decode('gbk'))
print('断开连接。。。')
client.close()

#解决方案3,自定义4字节报头,发送数据

#server.py
import socket
import struct
import json
import os
tcp_server = socket.socket()
ip_port = ('127.0.0.1',8001) #127.0.0.1本机的回环地址,供内部程序之间测试用的
tcp_server.bind(ip_port)
tcp_server.listen()
#客户端上传的文件路径,都放在这个路径下
client_file_path = r'D:jj'

conn,addr = tcp_server.accept()
#首先接收到文件信息长度转换出来的4个字节的数据
file_info_stru = conn.recv(4)
#解包文件信息的长度
file_info_len = struct.unpack('i',file_info_stru)[0]
#然后接收文件的描述信息
client_file_info = conn.recv(file_info_len).decode('utf-8')
#将接收到的json字符串反序列化
abc_file_info = json.loads(client_file_info)
print('abc_file_info>>>',abc_file_info)
client_file_size = abc_file_info['file_size']

recv_all_size = 0

#拼接一下全路径
client_full_path = client_file_path + '\' + abc_file_info['file_name']
# client_full_path = os.path.join(client_file_path,abc_file_info['file_name'])
with open(client_full_path,'wb') as f:
    while recv_all_size < client_file_size:
        every_recv_data = conn.recv(1024)
        f.write(every_recv_data)
        recv_all_size += len(every_recv_data)


conn.send('小伙玩的行,上传成功!'.encode('utf-8'))
conn.close()
tcp_server.close()

#client.py
import socket
import struct
import os
import json

tcp_client = socket.socket()
server_ip_port = ('127.0.0.1',8001)
tcp_client.connect(server_ip_port)
read_size = 1024


file_info = {
    'file_path':r'D:python_workspaceday030aaa.mp4',
    'file_name':'aaa.mp4',
    'file_size':None,
}

#获取文件大小
file_size = os.path.getsize(file_info['file_path'])

#将文件大小添加到文件信息的字典中
file_info['file_size'] = file_size
#因为我们要发送的数据是字节类型,那么必须将字典转换为bytes类型,但是字典不能直接转换为bytes,所以我们想到了json,
#通过json模块将字典类型的文件信息数据转换为了json类型的字符串
file_info_json = json.dumps(file_info)
#获取了字符串的长度
file_info_len = len(file_info_json)
#将长度打包为4个字节的数据,
file_info_stru = struct.pack('i',file_info_len)
#将打包好的4个自己的数据和我的文件信息数据一起发送给了服务端
tcp_client.send(file_info_stru)
tcp_client.send(file_info_json.encode('utf-8'))

#统计文件数据
all_file_data = b''
#统计文件数据长度
all_size_len = 0

with open(file_info['file_path'],'rb') as f:
    while all_size_len < file_size:
        every_read_data = f.read(read_size)
        all_file_data += every_read_data
        all_size_len += len(every_read_data)
        #发送每次读取的数据
        tcp_client.send(every_read_data)

print(tcp_client.recv(1024).decode('utf-8'))
tcp_client.close()

  

原文地址:https://www.cnblogs.com/PythonMrChu/p/9837822.html