11.1、socket连接中的粘包、精确传输问题
粘包:
发生原因:
当调用send的时候,数据并不是即时发给客户端的。而是放到了系统的socket发送缓冲区里,等缓冲区满了、或者数据等待超时了,数据才会发送,所以有时候发送太快的话,前一份数据还没有传给客户端,那么这份数据和上一份数据一起发给客户端的时候就会造成“粘包” 。
解决方案:
解决根源的思想是避免不同段的数据一起发送。
- 方案1:前一段数据send完后,等待一段时间再send第二段数据。缺点:时间效率低,而且也无法完全避免问题【因为不清楚该设置多少时间才能保证前一份数据已经发送】
- 方案2:握手机制:前一段数据send完后,尝试recv,等待客户端回应,确认第一段数据发送完后,再send第二段数据。完美方案?
方案二的演示:
服务端【发送方】代码:
import socket server=socket.socket()
server.bind(("localhost",1234))
server.listen() while True:
print("正在等待。。。")
conn,addr=server.accept()
while True:
try:
conn.send(b"first info")
ack=conn.recv(1024) #接收客户端确认
print(ack)
conn.send(b"second info")
except ConnectionResetError as e:
print(e)
break server.close()
客户端【接收方】代码:
import socket
client=socket.socket()
client.connect(("localhost",1234))
data=client.recv(1024)
print(data.decode())
client.send(b"ack")#发送确认
data=client.recv(1024)
print(data.decode())
client.close()
不精确传输问题:
发生原因:
由于数据太大,发送方一次send不完,而接收方只recv一次,使得影响了后面数据的传输
解决方案:
解决根源的思想是改变recv的次数。
- 方案:将数据的大小发给接收方,让接收方来决定recv的次数
方案实现代码【以解决长数据shell命令传输为例】:
服务端【发送方】:
import socket,os server=socket.socket()
server.bind(("localhost",1234))
server.listen()
while True:
print("正在等待...")
conn,addr=server.accept()
print("连接成功!")
while True:
try:
cmd=conn.recv(1024)
data=os.popen(cmd.decode()).read()
# print(data)
cmd_len=len(data.encode())
print(cmd_len)
#发现这里如果cmd_len为0会导致异常,有些是没有返回值的command
if cmd_len==0:
data="command has nothing return"
cmd_len=len(data.encode())
##因为这里前面没有发送操作,所以不用担心粘包,如果有则要考虑处理
conn.send(str(cmd_len).encode())#因为len结果是int,所以还要转换
#这里要处理粘包
ack=conn.recv(1024)
conn.send(data.encode())
except ConnectionResetError as e:
print(e)
break server.close()
客户端【接收方】:
import socket client=socket.socket()
client.connect(("localhost",1234))
while True: cmd = input(">>:")
client.send(cmd.encode())
data_len=client.recv(1024)
data_len=int(data_len.decode())
print(data_len)
recv_len=0
client.send(b'ack')
total_data=b''
while recv_len<data_len:
data=client.recv(1024)
recv_len+=len(data)
total_data+=data
print(total_data.decode())
client.close()
- 利用这个原理可以实现文件传输,只要能确定接受次数,就能保证文件传输的大小正确。
11.1、socket连接中的粘包、精确传输问题的更多相关文章
- c# Socket通讯中关于粘包,半包的处理,加分割符
using System; using System.Collections.Generic; using System.Text; using System.Net.Sockets; using S ...
- python socket的应用 以及tcp中的粘包现象
1,socket套接字 一个接口模块,在tcp/udp协议之间的传输接口,将其影藏在socket之后,用户看到的是socket让其看到的. 在tcp中当做server和client的主要模块运用 #s ...
- python中TCP协议中的粘包问题
TCP协议中的粘包问题 1.粘包现象 基于TCP实现一个简易远程cmd功能 #服务端 import socket import subprocess sever = socket.socket() s ...
- python中TCP粘包问题解决方案
TCP协议中的粘包问题 1.粘包现象 基于TCP写一个远程cmd功能 #服务端 import socket import subprocess sever = socket.socket() seve ...
- Netty 中的粘包和拆包
Netty 底层是基于 TCP 协议来处理网络数据传输.我们知道 TCP 协议是面向字节流的协议,数据像流水一样在网络中传输那何来 "包" 的概念呢? TCP是四层协议不负责数据逻 ...
- 什么是粘包? socket 中造成粘包的原因是什么? 哪些情况会发生粘包现象?
只有TCP有粘包现象,UDP永远不会粘包! 粘包:在接收数据时,一次性多接收了其它请求发送来的数据(即多包接收).如,对方第一次发送hello,第二次发送world, 在接收时,应该收两次,一次是he ...
- socket基于TCP(粘包现象和处理)
目录 6socket套接字 7基于TCP协议的socket简单的网络通信 AF_UNIX AF_INET(应用最广泛的一个) 报错类型 单一 链接+循环通信 远程命令 9.tcp 实例:远程执行命令 ...
- day8---多线程socket 编程,tcp粘包处理
复习下socket 编程的步骤: 服务端: 1 声明socket 实例 server = socket.socket() #括号里不写 默认地址簇使用AF_INET 即 IPv4 ...
- python socket网络编程之粘包问题详解
一,粘包问题详情 1,只有TCP有粘包现象,UDP永远不会粘包 你的程序实际上无权直接操作网卡的,你操作网卡都是通过操作系统给用户程序暴露出来的接口,那每次你的程序要给远程发数据时,其实是先把数据从用 ...
随机推荐
- Spring Boot Debug调试
在使用spring-boot:run进行启动的时候,如果设置的断点进不去,要进行以下的设置. 1.添加jvm参数配置 在spring-boot的maven插件加上jvmArguments配置. < ...
- win10 store 无法连接网络(原创)
当你试过所有的解决攻略 都无效时,那么使用这个教程 关闭以下的蓝色框里的
- html css 其他常用 onclick跳转
opacity: 0.5. 0-1 透明度 cursor: pointer;手指 clear:both 清楚浮动 我是医生不是人 文本内容超出框word-wrap:break-word; word-b ...
- xml与Excel转换
使用Python将如下xml格式转换为Excel格式: xml转为xls格式文件: xml格式如下: <?xml version="1.0" encoding="U ...
- Java高并发之设计模式
本文主要讲解几种常见并行模式, 具体目录结构如下图. 单例 单例是最常见的一种设计模式, 一般用于全局对象管理, 比如xml配置读写之类的. 一般分为懒汉式, 饿汉式. 懒汉式: 方法上加synchr ...
- simhash文章排重
原文链接:https://www.cnblogs.com/baochuan/p/9089244.html 背景 提升产品体验,节省用户感知度.——想想,如果看到一堆相似性很高的新闻,对于用户 ...
- Docz 用 MDX 写 React UI 组件文档
Docz 用 MDX 写 React UI 组件文档 前言 为了提升开发效率,创建一套 UI 组件库是一种较为有效的方式之一:可以减少重复工作.提高可复用,所以现在越来越多团队开始创建自己的 UI 组 ...
- Django | 模型类变更后生成迁移文件,报错:You are trying to add a non-nullable field 'BookName' to BookInfo without a default....
报错: You are trying to add a non-nullable field 'BookName' to BookInfo without a default; we can't do ...
- Netty入门——客户端与服务端通信
Netty简介Netty是一个基于JAVA NIO 类库的异步通信框架,它的架构特点是:异步非阻塞.基于事件驱动.高性能.高可靠性和高可定制性.换句话说,Netty是一个NIO框架,使用它可以简单快速 ...
- Kafka命令清单
一.队列常用命令 #创建topics $ ./kafka-topics.sh --create --zookeeper chenx02:2181 --replication-factor 1 --pa ...