zoukankan      html  css  js  c++  java
  • 通过制定报头解决粘包问题

    #1.什么是粘包?
    #粘包就是在获取数据时,出现数据的内容不是本应该接收的数据,如:对方第一次发送hello,第二次发送world,
    #我放接收时,应该收两次,一次是hello,一次是world,但事实上是一次收到helloworld,一次收到空,这种现象
    #叫粘包
    #2.出现粘包的原因:在给对方发送消息时,是先把消息发给自己的操作系统(内存),然后通过操作系统-->网络-->对方
    #的操作系统,对方在到自己的操作系统中获取信息,也就是说不管是发送信息还是接收信息,我们只能是在自己的操作
    #系统中进行,不是直线发送或接收对方的信息,而操作系统具有延迟性,所以出现了粘包
    #3.粘包的解决,是通过设置报头,在传信息之前,先把该信息的报头传给对方,在传该信息,就不会出现粘包
    #4.报头是一个字典,它含有信息的大小,还有可以有文件的名称,文件的hash值,如下
    #head_dic={'size':len(data),'filename':filenaem,'hash':hash值},如果还有,可以继续在字典中加
    服务端:
    import struct
    import subprocess
    import json
    import socket
    phone =socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
    ip_port =('127.0.0.1',8088)
    phone.bind(ip_port)
    max_request_size =5
    phone.listen(max_request_size)
    while True:
    print('starting.....')
    conn,addr =phone.accept()
    print('客户端的addr是:',addr)
    while True:
    try:
    data =conn.recv(1024)
    res =subprocess.Popen(data.decode('utf-8'),shell=True,
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE)
    res_out =res.stdout.read()
    res_err =res.stderr.read()
    #制作报头
    res_size =len(res_out)+len(res_err)
    head_dic ={'size':res_size,'hash':None}
    head_json =json.dumps(head_dic)
    head_bytes =head_json.encode('utf-8')
    #先发报头的长度
    head_len =len(head_bytes)
    conn.send(struct.pack('i',head_len))

    #在发报头
    conn.send(head_bytes)
    #最后发送信息
    conn.send(res_out)
    conn.send(res_err)
    except Exception:
    break

    conn.close()
    phone.close()
    客户端
    import struct
    import json
    import socket
    phone =socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    ip_port =('127.0.0.1',8088)
    phone.connect(ip_port)
    while True:
    msg =input('>>>:').strip()
    #phone.send(b'hello')
    if not msg:
    continue
    phone.send(msg.encode('utf-8'))

    #先收报头的长度
    head_struct =phone.recv(4)
    head_len =struct.unpack('i',head_struct)[0]

    #在收报头
    head_bytes =phone.recv(head_len)
    head_json =head_bytes.decode('utf-8')
    head_dic =json.loads(head_json)

    #在收信息
    data_size =head_dic['size']
    recv_size =0
    recv_data =b''
    while recv_size <data_size:
    data =phone.recv(1024)
    recv_size+=len(data)
    recv_data+=data

    print(recv_data.decode('gbk')) #如果服务端在linux中,就用utf-8解码

    phone.close()
  • 相关阅读:
    移动端开发基础【4】uniapp项目发布
    移动端开发案例【3】通讯录开发
    移动端开发基础【2】uni-app项目调试
    np.cross, np.count_nonzeros, np.isnan, np.transpose
    numpy中用None扩充维度
    NTU RGB+D数据集,骨架数据可视化
    文件映射,mmap
    转:Python pickle模块:实现Python对象的持久化存储
    Temporal Convolutional Networks (TCN)资料,扩张卷积
    梯度消失和爆炸,RNN,LSTM
  • 原文地址:https://www.cnblogs.com/IQ-Python/p/6807984.html
Copyright © 2011-2022 走看看