原创博客>>>解决粘包问题的方法

  • 服务端:

    import socket
    import struct
    service=socket.socket() service.bind(('127.0.0.1',8081))
    while True:
    service.listen(5) conn,address=service.accept()
    print('有客户端连接进来了,地址如下',address)
    data_len_byte=conn.recv(4)
    # print(data_len_byte)
    data_len=struct.unpack('i',data_len_byte)[0]#把数据长度的字节码再转int
    data=conn.recv(data_len)
    print('我收到了客户端的数据',data)
    conn.send(b'ok')
  • 客户端

    import socket
    import struct
    client=socket.socket()
    client.connect(('127.0.0.1', 8081)) msg=input('helloword,input>>>>')
    # print(msg.encode('utf8'))
    #把数据字节码的长度转为字节码 这个字节码固定是四位的
    msg_len_byte=struct.pack('i',len(msg.encode('utf8')))
    client.send(msg_len_byte)
    msg_byte=msg.encode('utf8')
    client.send(msg_byte)
    data=client.recv(4)
    print('来自服务端的信息',data)

以上的解决思路:客户端第一个send()往服务端发送固定长度为4 的字节码(客户端接下来要发送的真正内容的长度的字节码) ,然后服务端这边,第一个的recv(4)接收到这个数据的时候,就等于获取到了客户端接下来要发送的数据的字节码长度len,这个len作为接下来服务端接收的recv(len)的长度参数,客户端发送真正的数据的字节码后,服务端的recv(len)就完完整整的收到了真正的数据,一字不少不多。

以上思路是针对于一种是粘在一起的包都是完整的数据包的粘包问题

以下思路是针对于粘在一起的包有不完整的包。

于是对以上的问题再次升级,代码放出

  • 服务端
import socket
import subprocess
import struct
soc=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
soc.bind(('127.0.0.1',8001))
soc.listen(3)
while True:
print('等待客户端连接')
conn,addr=soc.accept()
print('有个客户端连接上了',addr)
while True:
try:
data=conn.recv(1024)
if len(data)==0:
break
print(data)
obj = subprocess.Popen(str(data,encoding='utf-8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
#执行正确的结果 b 格式,gbk编码(windows平台)
msg=obj.stdout.read() #发送的时候需要先把长度计算出来
#头必须是固定长度
#先发4位,头的长度
import json
dic={'size':len(msg)}
dic_bytes=(json.dumps(dic)).encode('utf-8')
#head_count是4个字节的长度
head_count=struct.pack('i',len(dic_bytes))
print(dic)
conn.send(head_count)
#发送头部内容
conn.send(dic_bytes)
#发了内容
conn.send(msg)
except Exception: break
# 关闭通道
conn.close() # 关闭套接字
soc.close()
  • 客户端
import socket
import struct
import json
soc=socket.socket() soc.connect(('127.0.0.1',8001))
while True:
in_s=input('请输入要执行的命令:')
soc.send(in_s.encode('utf-8'))
#头部字典的长度
head_dic_len=soc.recv(4)
#解出真正的长度
head_l=struct.unpack('i',head_dic_len)[0]
#byte 字典的长度
#收真正的头部字典
dic_byte=soc.recv(head_l)
head=json.loads(dic_byte)
print(head)
l=head['size']
count=0
data_total=b''
print(l)
#核心代码
while count<l:
if l<1024: #如果接受的数据小于1024 ,直接接受数据大小
data=soc.recv(l)
else:#如果接受的数据大于1024
if l-count>=1024: #总数据长度-count(目前收到多少,count就是多少) 如果还大于1024 ,在收1024
data=soc.recv(1024)
else: #总数据长度-count(目前收到多少,count就是多少) 如果小于1024,只收剩下的部分就可
data=soc.recv(l-count) data_total+=data
count+=len(data) print(str(data_total,encoding='gbk'))

思路:为了把粘在一起的包有不完整的包问题更加明显,特意找了subprocess模块,这个模块可以模拟cmd,输入tasklist命令的结果是很长的字节码,一般情况下recv(n)第一次只能打印前n个字节码,总之一次只能打印不完整的数据,必须多次打印接下来剩下的数据,于是就套用了while true,通过while true循环 拼接字节码 拼接整个数据的字节码,if判断读到的剩下数据是否到尾巴,到了尾巴将while 终止break,最后 将完整的数据的字节码打印出来。

原创博客>>>解决粘包问题的方法的更多相关文章

  1. netty解决粘包半包问题

    前言:开发者用到TCP/IP交互时,偶尔会遇到粘包或者半包的数据,这种情况有时会对我们的程序造成严重的影响,netty框架为解决这种问题提供了若干框架 1. LineBasedFrameDecoder ...

  2. 网络编程基础【day09】:socket解决粘包问题之MD5(八)

    本节内容 1.概述 2.代码实现 一.概述 上一篇博客讲到的用MD5来校验还是用的之前解决粘包的方法,就是客户端发送一个请求,等待服务端的确认的这样的一个笨方法.下面我们用另外一种方法:就是客户端已经 ...

  3. c# socket 解决粘包,半包

    处理原理: 半包:即一条消息底层分几次发送,先有个头包读取整条消息的长度,当不满足长度时,将消息临时缓存起来,直到满足长度再解码 粘包:两条完整/不完整消息粘在一起,一般是解码完上一条消息,然后再判断 ...

  4. Socket解决粘包问题1

    粘包是指发送端发送的包速度过快,到接收端那边多包并成一个包的现象,比如发送端连续10次发送1个字符'a',因为发送的速度很快,接收端可能一次就收到了10个字符'aaaaaaaaaa',这就是接收端的粘 ...

  5. python3全栈开发-什么是粘包、粘包现象、如何解决粘包

    一.粘包现象 让我们基于tcp先制作一个远程执行命令的程序(1:执行错误命令 2:执行ls 3:执行ifconfig) 注意注意注意: res=subprocess.Popen(cmd.decode( ...

  6. Netty解决粘包和拆包问题的四种方案

    在RPC框架中,粘包和拆包问题是必须解决一个问题,因为RPC框架中,各个微服务相互之间都是维系了一个TCP长连接,比如dubbo就是一个全双工的长连接.由于微服务往对方发送信息的时候,所有的请求都是使 ...

  7. Python开发【socket篇】解决粘包

    客户端 import os import json import struct import socket sk = socket.socket() sk.connect(('127.0.0.1',8 ...

  8. python全栈开发day28-网络编程之粘包、解决粘包,上传和下载的作业

    一.昨日内容回顾 1. tcp和udp编码 2. 自定义mysocket解决编码问题 二.今日内容总结 1.粘包 1)产生粘包原因: (1).接收方不知道消息之间的边界,不知道一次性要取多少字节的数据 ...

  9. Dealing with a Stream-based Transport 处理一个基于流的传输 粘包 即使关闭nagle算法,也不能解决粘包问题

    即使关闭nagle算法,也不能解决粘包问题 https://waylau.com/netty-4-user-guide/Getting%20Started/Dealing%20with%20a%20S ...

随机推荐

  1. ES 可视化工具

    1.ElasticSearch Head 用途:展示ES(集群)数据信息 视图:https://mobz.github.io/elasticsearch-head/ 下载:https://github ...

  2. JAVA 基础编程练习题4 【程序 4 分解质因数】

    4 [程序 4 分解质因数] 题目:将一个正整数分解质因数.例如:输入 90,打印出 90=2*3*3*5. 程序分析:对 n 进行分解质因数,应先找到一个最小的质数 k,然后按下述步骤完成: (1) ...

  3. SpringBoot之解决一对一、多对一、多对多等关联实体在JSON序列化/输出时产生的无限递归死循环问题(infinite recursion)

    前言 这问题着实让人苦不堪言,有必要把它记下了. @JsonBackReference [亲测有效] 1.使用注解@JsonBackReference标记在有关联关系的实体属性上 2.仅导入此注解类有 ...

  4. (转载)悟透JavaScript

    引子 编程世界里只存在两种基本元素,一个是数据,一个是代码.编程世界就是在数据和代码千丝万缕的纠缠中呈现出无限的生机和活力. 数据天生就是文静的,总想保持自己固有的本色:而代码却天生活泼,总想改变这个 ...

  5. mysql 批量kill locked 进程

    mysql -s -e "show processlist;" | grep 'Sending data' | awk '{print "kill "$1&qu ...

  6. 哈希算法MD5和SHA1的C#实现

    /* * 哈希算法MD5和SHA1的C#实现 *  *  * 夏春涛 Email:xChuntao@163.com  * Blog:http://bluesky521.cnblogs.com * 运行 ...

  7. 【Zookeeper】本地模式安装

    安装步骤 上传gz包 通过rz命令,将zookeeper-3.4.10.tar.gz安装包上传到/opt/soft/文件夹下. [root@bigdata111 soft]# rz [root@big ...

  8. Docker的数据管理(volume/bind mount/tmpfs)

    Docker提供了三种不同的方式用于将宿主的数据挂载到容器中:volumes,bind mounts,tmpfs volumes.当你不知道该选择哪种方式时,记住,volumes总是正确的选择. vo ...

  9. 图表:WebChartControl

    #region 画统计图 /// <summary> /// 画统计图 /// </summary> private void LoadWebChartControl() { ...

  10. 2019牛客暑期多校训练营(第六场)-E Androgynos (构造题)

    题目链接:https://ac.nowcoder.com/acm/contest/886/E 题意:给出n,求能否构造一个含n个顶点的简单无向图,且它的补图与它同构. 思路:首先要满足与其补图同构,同 ...