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客户端

 

 

 

 

 

posted @ 2017-08-23 15:37  孟庆健  阅读(167)  评论(0编辑  收藏  举报