zoukankan      html  css  js  c++  java
  • python之socket--粘包补充

    struct补充

    import struct
    import json
    header_dic={'total_size':123123,
                'filename':None,
                'md5':None}
    
    header_json=json.dumps(header_dic)
    header_bytes=header_json.encode('utf-8')
    # print(header_bytes,type(header_bytes))
    print(len(header_bytes))
    struct补充

    解决粘包问题(json)

    import socket
    import subprocess
    import struct
    import json
    phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机
    phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #就是它,在bind前加
    phone.bind(('127.0.0.1',8082)) #绑定手机卡
    phone.listen(5) #开机
    print('starting...')
    while True: #链接循环
        conn,client_addr=phone.accept() #等电话 (链接,客户的的ip和端口组成的元组)
        print('-------->',conn,client_addr)
        #收,发消息
        while True:#通信循环
            try:
                cmd=conn.recv(1024)
                if not cmd:break #针对linux
                #执行cmd命令,拿到cmd的结果,结果应该是bytes类型
                #。。。。
                res = subprocess.Popen(cmd.decode('utf-8'), shell=True,
                                       stdout=subprocess.PIPE,
                                       stderr=subprocess.PIPE)
                stdout=res.stdout.read()
                stderr=res.stderr.read()
                #制作报头
                header_dic = {
                    'total_size': len(stdout)+len(stderr),
                    'filename': None,
                    'md5': None}
                header_json = json.dumps(header_dic)
                header_bytes = header_json.encode('utf-8')
                #发送阶段
                #先发报头长度
                conn.send(struct.pack('i',len(header_bytes)))
                #再发报头
                conn.send(header_bytes)
                #最后发送命令的结果
                conn.send(stdout)
                conn.send(stderr)
            except Exception:
                break
        conn.close() #挂电话
    phone.close() #关机
    服务端
    import socket
    import struct
    import json
    phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机
    phone.connect(('127.0.0.1',8082)) #绑定手机卡
    #发,收消息
    while True:
        cmd=input('>>: ').strip()
        if not cmd:continue
        phone.send(cmd.encode('utf-8'))
        #先收报头的长度
        header_len=struct.unpack('i',phone.recv(4))[0]
        #再收报头
        header_bytes=phone.recv(header_len)
        header_json=header_bytes.decode('utf-8')
        header_dic=json.loads(header_json)
        total_size=header_dic['total_size']
        #最后收数据
        recv_size=0 #10241=10240+1
        total_data=b''
        while recv_size < total_size:
            recv_data=phone.recv(1024)
            recv_size+=len(recv_data)
            total_data+=recv_data
        print(total_data.decode('gbk'))
    phone.close()
    客户端

    基于udp的套接字

          udp是无连接的,先启动那一端都不会报错

    from socket import *
    udp_server=socket(AF_INET,SOCK_DGRAM)
    udp_server.bind(('127.0.0.1',8088))
    
    while True:
        msg,client_addr=udp_server.recvfrom(1024)
        print('has recv %s' %msg)
        udp_server.sendto(msg.upper(),client_addr)
        print('has send')
    udp_server.close()
    基于udp套接字的服务端
    from socket import *
    udp_client=socket(AF_INET,SOCK_DGRAM)
    
    while True:
        msg=input('>>: ').strip()
        udp_client.sendto(msg.encode('utf-8'),('127.0.0.1',8088))
        print('has send')
        # res,server_addr=udp_client.recvfrom(1024)
        # print('====>',res.decode('utf-8'))
    
    udp_client.close()
    基于udp套接字的客户端

    udp协议不会粘包

    from socket import *
    udp_server=socket(AF_INET,SOCK_DGRAM)
    udp_server.bind(('127.0.0.1',8089))
    
    msg1,client_addr=udp_server.recvfrom(5)
    print(msg1)
    
    msg2,client_addr=udp_server.recvfrom(5)
    print(msg2)
    udp服务端
    from socket import *
    udp_server=socket(AF_INET,SOCK_DGRAM)
    udp_server.bind(('127.0.0.1',8089))
    
    msg1,client_addr=udp_server.recvfrom(5)
    print(msg1)
    
    msg2,client_addr=udp_server.recvfrom(5)
    print(msg2)
    udp客户端

     

  • 相关阅读:
    STL 之 unordered_map
    vim tab和空格相互替换
    windows使用
    debugger打不开
    存储过程中执行动态Sql语句
    什么是详细设计说明书?
    C#中调用SQL存储过程(带输入输出参数的例子)
    如何解决网站在IE8下出现布局乱的情况?
    SQLServer 游标简介与使用说明
    线程池ThreadPoolExecutor参数设置
  • 原文地址:https://www.cnblogs.com/mengqingjian/p/7418473.html
Copyright © 2011-2022 走看看