• 网络编程之粘包解决方案


    #解决方案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()
    

      

  • 相关阅读:
    Elasticsearch本地环境安装和常用操作
    Scala快速入门
    Flink本地安装和创建Flink应用
    Elasticsearch源码分析
    android6,0申请权限
    JDK动态代理
    Navicat 连接MySQL8.0,错误:Authentication plugin 'caching_sha2_password' cannot be loaded
    mysqldump
    mysql配置远程登录
    将博客搬至CSDN
  • 原文地址:https://www.cnblogs.com/PythonMrChu/p/9837822.html
Copyright © 2020-2023  润新知