tcp协议传输中的粘包问题
什么是粘包问题
tcp是流体协议. 其nagle算法会将数据量较小. 并且发送间隔时间较短的多个数据包合并为一个发送. 网络传输的时候是一段一段字节流的发送. 在接收方看来根本不知道字节流从何开始. 在哪里结束. 所以粘包问题就是接收方不知道消息之间的界限. 不止到一次性提取多少数据导致的
而udp协议的是面向消息的协议. 每一段的udp都是一段消息. 应用程序必须以消息作为单位提取. 不能提取任意自己的数据. 所以不存在粘包问题
怎么解决粘包问题
设置一个固定的报头. 报头中含有真实数据的长度信息. 然后客户端就可以根据报头的数据去接收相应字节. 从而避免粘包现象. 总结起来就是一开始将真实数据长度通过报头传递给客户端. 后面都是环环相扣
具体代码
前面都是理论部分. 后面咱们来看看怎么进行实操解决粘包问题. 解决粘包问题的关键就是让客户端知道数据之间的界限在哪.
# 服务端.py
# -*- encoding:utf-8 -*-
# @time: 2022/7/30 13:07
# @author: Maxs_hu
"""
以前有种比较low的方式(alex)是使用time.sleep将数据流之间断开. 当然这种自己设置网络延迟的方式当然是不可取的
"""
from socket import *
import subprocess
import json
import struct
socket = socket(AF_INET, SOCK_STREAM)
socket.bind(('127.0.0.1', 8000))
socket.listen(5)
while True: # 链接循环
print('---服务器开始运行---')
conn, client_addr = socket.accept()
print(client_addr)
while True:
try:
cmd = conn.recv(1024)
if len(cmd) == 0:
break
obj = subprocess.run(cmd.decode('utf8'),
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
encoding='gbk'
)
stdout = obj.stdout.encode('utf8')
stderr = obj.stderr.encode('utf8')
data_size = len(stderr+stdout)
# 1. 制作合理的表头数据
header_dic = {
'filename': 'a.txt',
'total_size': data_size,
'hashlib': 'fdfadfadf343jkafjdxkfjc'
}
# 将字典转化成可以传输的格式. 并计算出len
header_json = json.dumps(header_dic)
header_byte = header_json.encode('utf8')
header_len = struct.pack('i', len(header_byte))
# 1. 先将表头长度进行传递
conn.send(header_len)
# 2. 再将表头数据进行传输
conn.send(header_byte)
# 3. 在传输真实的数据
conn.send(stderr+stdout)
except ConnectionResetError:
break
conn.close()
# 客户端.py
# -*- encoding:utf-8 -*-
# @time: 2022/7/30 13:07
# @author: Maxs_hu
from socket import *
import struct
import json
client = socket(AF_INET, SOCK_STREAM)
client.connect(('127.0.0.1', 8000))
while True:
cmd = input('请输入命令>>>').strip()
if len(cmd) == 0:
break
client.send(cmd.encode("utf8"))
# 1. 先接收表头长度
header_len = client.recv(4)
header_size = struct.unpack('i', header_len)[0]
# 2. 根据表头的长度去接收表头
header = client.recv(header_size)
# 解析表头数据
header_dic = json.loads(header.decode('utf8'))
print(header_dic)
total_size = header_dic['total_size']
recv_size = 0
data = b''
while recv_size < total_size:
data += client.recv(1024)
recv_size = len(data)
print(data.decode('utf8'))
client.close()
tcp协议传输中的粘包问题的更多相关文章
- python 之网络编程(基于TCP协议Socket通信的粘包问题及解决)
8.4 粘包问题 粘包问题发生的原因: 1.发送端需要等缓冲区满才发送出去,造成粘包(发送数据时间间隔很短,数据了很小,会合到一起,产生粘包),这样接收端,就难于分辨出来了,必须提供科学的拆包机制. ...
- python中TCP协议中的粘包问题
TCP协议中的粘包问题 1.粘包现象 基于TCP实现一个简易远程cmd功能 #服务端 import socket import subprocess sever = socket.socket() s ...
- python socket的应用 以及tcp中的粘包现象
1,socket套接字 一个接口模块,在tcp/udp协议之间的传输接口,将其影藏在socket之后,用户看到的是socket让其看到的. 在tcp中当做server和client的主要模块运用 #s ...
- Netty 中的粘包和拆包
Netty 底层是基于 TCP 协议来处理网络数据传输.我们知道 TCP 协议是面向字节流的协议,数据像流水一样在网络中传输那何来 "包" 的概念呢? TCP是四层协议不负责数据逻 ...
- 如何确保TCP协议传输稳定可靠?
TCP,控制传输协议,它充分实现了数据传输时的各种控制功能:针对发送端发出的数据包确认应答信号ACK:针对数据包丢失或者出现定时器超时的重发机制:针对数据包到达接收端主机顺序乱掉的顺序控制:针对高效传 ...
- Netty--使用TCP协议传输文件
简介: 用于将文件通过TCP协议传输到另一台机器,两台机器需要通过网络互联. 实现: 使用Netty进行文件传输,服务端读取文件并将文件拆分为多个数据块发送,接收端接收数据块,并按顺序将数据写入文件. ...
- TCP协议传输大文件读取时候的问题
TCP协议传输大文件读取时候的问题 大文件传不完的bug 我们在定义的时候定义服务端每次文件读取大小为10240, 客户端每次接受大小为10240 我们想当然的认为客户端每次读取大小就是10240而把 ...
- tcp协议传输方法&粘包问题
socket实现客户端和服务端 tcp协议可以用socket模块实现服务端可客户端的交互 # 服务端 import socket #生成一个socket对象 soc = socket.socket(s ...
- Socket 编程中,TCP 流的结束标志与粘包问题
因为 TCP 本身是无边界的协议,因此它并没有结束标志,也无法分包. socket和文件不一样,从文件中读,读到末尾就到达流的结尾了,所以会返回-1或null,循环结束,但是socket是连接两个主机 ...
随机推荐
- Proxmox 5.4使用vgpu_unlock,为GTX1060开启vGPU支持
本文介绍如何为GTX1060显卡开启vGPU功能.消费级显卡不支持nvidia GRID vGPU功能.在2021年初,疫情激发了黑客的创作热情,给出了一个vgpu_unlock的补丁,可以让消费级显 ...
- ethtools-网卡适配器管理
查看网卡适配器配置信息,并且我们可以通过它修改网卡适配器的双工模式. 1.安装Ethtools [root@localhost ~]# yum -y install ethtools 2.命令语法 语 ...
- 在 Pisa-Proxy 中,如何利用 Rust 实现 MySQL 代理
一.前言 背景 在 Database Mesh 中,Pisanix 是一套以数据库为中心的治理框架,为用户提供了诸多治理能力,例如:数据库流量治理,SQL 防火墙,负载均衡和审计等.在 Pisanix ...
- 编写一个kubernetes controller
Overview 根据Kuberneter文档对Controller的描述,Controller在kubernetes中是负责协调的组件,根据设计模式可知,controller会不断的你的对象(如Po ...
- 驱动开发实战之TcpClient
场景模拟 假设你有一批非标设备需要对接,对方提供了如下协议文档: 协议概述 设备作为TCPServer,端口6666 字节序:Little-Endian,即低地址存放低位 请求回复 需要你主动发起读取 ...
- ant design pro生产和开发环境的坑
1.axios的get请求开发环境会自动带上cookie,但是生产环境则不会,需要手动设置以下代码: axios.defaults.withCredentials=true; 2.models全局和局 ...
- SAP Web Dynpro - 教程
SAP Web Dynpro是一种标准的SAP UI技术,用于使用图形工具和与ABAP工作台集成的开发环境来开发Web应用程序. 图形工具的使用减少了实施工作,并有助于维护ABAP工作台中的组件. 本 ...
- Kubebuilder模块
CRD创建 Group表示CRD所属的组,它可以支持多种不同版本.不同类型的资源构建,Version表示CRD的版本号,Kind表示CRD的类型 kubebuilder create api --gr ...
- 【RPA之家转载RPA创新产业峰会回看】机器人流程自动化专利态势报告
[RPA之家转载RPA创新产业峰会回看]机器人流程自动化专利态势报告 自动化的一个专利情况的监测,就是全球监测的情况.今天我可能给大家汇报的主要是三个方面,第一个方面就是讲一下全球投资智能化的专利的一 ...
- Mysql安装配置以及解决重装Mysql时忘记root password问题
目录 1.Mysql安装以及环境变量配置 重装Mysql时忘记root password问题 1.Mysql安装以及环境变量配置 官网安装:https://www.mysql.com/ 按 ...