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

  • 服务端:

    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. Cgroup与LXC简介

    原文地址: https://blog.51cto.com/speakingbaicai/1359825 一.Docker.LXC.Cgroup的结构关系 根据Docker布道师Jerome Petaz ...

  2. What happens when you type an URL in the browser and press enter?

    What happens when you type an URL in the browser and press enter? 1. You type maps.google.com into t ...

  3. java数据结构之LinkedHashMap

    一.LinkedHashMap源码注释 public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map& ...

  4. 树莓派使用c语言控制管脚--wiringPi安装

    树莓派先安装git,然后安装库 命令如下 git clone https://github.com/WiringPi/WiringPi cd wiringPi ./build 测试--输出管脚信息 g ...

  5. 【Zookeeper】本地模式安装

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

  6. vue自定义过滤器的创建与使用

    原文地址 过滤器:生活中有很多例子,净水器 空气净化器 .过滤器的作用:实现数据的筛选.过滤.格式化. vue1.*版本是有内置的过滤器,但是在vue2.*所有的版本都已经没有自带的过滤器了. 1.过 ...

  7. 如何简单的编译v8动态库

    按照google v8的官方提供的方法,在国内,完成编译简直太难了. 还好nodejs提供离线编译能力,稍微改造一下可以从node源码中直接编译纯净的v8动态库. 直接把v8解压出来的py/gpy文件 ...

  8. 记录一次maven打包时将test目录下的类打包到jar中,Maven Assembly Plugin的使用

    今天有人问我打包后找不到主类,运行的类写在test中.按照常规,test目录下的文件不会打包到jar包中.(但是我测试一个springboot工程就可以,这里之后再研究) 具体解决如下 第一步:在po ...

  9. VMware Conveter Standalone agent 安装时出现Error 29190错误的解决办法

    官网上面找的: if it helps anyone else, i found a workaround for my particular issue. on the source machine ...

  10. 【Python】【demo实验7】【练习实例】【完全平方数相关】

    题目:一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少? 程序分析:可填在百位.十位.个位的数字都是1.2.3.4.组成所有的排列后再去 掉不满足条件的排列. ...