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永远不会粘包 你的程序实际上无权直接操作网卡的,你操作网卡都是通过操作系统给用户程序暴露出来的接口,那每次你的程序要给远程发数据时,其实是先把数据从用 ...
随机推荐
- JavaScript中子类调用父类方法的实现
一.前言 最近在项目中,前端框架使用JavaScript面向对象编程,遇到了诸多问题,其中最典型的问题就是子类调用父类(super class)同名方法,也就是如C#中子类中调用父类函数base.** ...
- Spring.Net实现跨数据库服务层事务管理
在实际项目中用了Spring.Net框架之后,发现这框架在处理数据库事务上特别强大,声明式的数据库事务解放了一般开发人员对数据库事务操作的复杂处理.尤其是多数据库事务处理上,尤为显得更简便,几个简单的 ...
- SpringBoot初探(上传文件)
学了Spring,SpringMVC,Mybatis这一套再来看SpringBoot,心里只有一句握草,好方便 这里对今天做的东西做个总结,然后在这之间先安利一个热部署的工具,叫spring-DevT ...
- app操作的一些命令
这里的操作都是在windows下,在android SDK安装好之后就可以连接实体手机或者模拟器操作 1.查看连接的手机或者模拟器 adb devices 结果如下: 2.查看某个app的包名和act ...
- 使用JDBC连接各种数据库
项目需要连多钟数据库,把链接的关键部分在这里记录下来. 1.Oracle8/8i/9i数据库(thin模式) Class.forName("oracle.jdbc.driver.Oracle ...
- Ubuntu 16.04下安装谷歌浏览器(转)
1.进入 Ubuntu 16.04 桌面,按下 Ctrl + Alt + t 键盘组合键,启动终端. 2.在终端中,输入以下命令,将下载源加入到系统的源列表. sudo wget http://www ...
- HTML 滚动条样式修改
<style> .innerbox{ overflow-y: auto; background-color: #f8f8f8; height: 200px; padding: 10px; ...
- 线程安全-005-synchronized其他概念
一.Synchornized锁重入 例子程序: package com.lhy.thread01; public class SyncDouble1 { public synchronized voi ...
- MyBatis大杂烩
1. 集成到SpringBoot项目中 核心依赖是org.mybatis.spring.boot:mybatis-spring-boot-starter,当然还需要jdbc和数据库驱动 build.g ...
- Apache Flume 1.7.0 源码编译 导入Eclipse
前言 最近看了看Apache Flume,在虚拟机里跑了一下flume + kafka + storm + mysql架构的demo,功能很简单,主要是用flume收集数据源(http上报信息),放入 ...