socket模块粘包现象理解以及解决思路
粘包现象:
在socket网络程序中,TCP和UDP分别是面向连接和非面向连接的。因此TCP的socket编程,收发两端(客户端和服务器端)都要有成对的socket,因此,发送端为了将多个发往接收端的包,更有效的发到对方,使用了优化方法(Nagle算法),将多次间隔较小、数据量小的数据,合并成一个大的数据块,然后进行封包。这样,接收端,就难于分辨出来了,必须提供科学的拆包机制
对于UDP,不会使用块的合并优化算法,这样,实际上目前认为,是由于UDP支持的是一对多的模式,所以接收端的skbuff(套接字缓冲区)采用了链式结构来记录每一个到达的UDP包,在每个UDP包中就有了消息头(消息来源地址,端口等信息),这样,对于接收端来说,就容易进行区分处理了。所以UDP不会出现粘包问题。
粘包现象理解:
socket模块sned以及recv实现底层原理
- send
- 作用:将内存中的数据通过网卡发送出去
- 底层原理:将数据从程序内存中拷贝到操作系统,通过操作系统调用网卡接口发送到远程
- recv
- 作用:接收远程发送的数据,传入参数单位为字节
- 底层原理:网卡接收远程发过来的数据,然后将数据从操作系统内存拷贝到应用程序内存中
不管是recv还是send都不是直接发送或者接收对方的数据,而是操作自己的操作系统的内存,并且不是一个send对应一个recv,是根据recv接收数据的大小而决定
TCP协议传输优化算法:Nagle算法
- 将数据比较小的包,并且时间间隔很短的包合并成一个包,调一次网卡io将数据发送到远程,节省调用网卡io的时间,粘包现象是TCP底层传输优化算法造成的。
粘包现象结局思路
- 客户端循环接收数据,使用while循环判断数据是否接收完毕
- 服务端返回诗句是打包报头发送给客户端,客户端根据报头发送的数据长度截取发送数据的真实长度
服务端:
- 制作固定长度的报头
- 将报头打包发送给客户端(使用struct模块打包数据)
再发送真实数据,通过while循环判断是否接收完毕,接收完了则跳出循环
客户端
- 接收报头,指定接收报头的长度,使用struct打包将服务端发送的报头按照指定模式解析
解析报头获得真实数据的长度描述
可使用内置模块struct打包与解析数据长度,
- i模式:4个字节长度
- l模式:8个字节长度
socket模块粘包现象理解以及解决思路的更多相关文章
- python笔记8 socket(TCP) subprocess模块 粘包现象 struct模块 基于UDP的套接字协议
socket 基于tcp协议socket 服务端 import socket phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 买 ...
- python3全栈开发-什么是粘包、粘包现象、如何解决粘包
一.粘包现象 让我们基于tcp先制作一个远程执行命令的程序(1:执行错误命令 2:执行ls 3:执行ifconfig) 注意注意注意: res=subprocess.Popen(cmd.decode( ...
- 网络 --- 3 socket模块 粘包
一 .socket 模块参数及方法 二.缓冲区 三.粘包 1.两种粘包现象 ①连续的小包可能会被优化算法给组合到一起进行发送 ②第一次如果发送的数据大小2000B接收端一次性接受大小为1024, 这就 ...
- TCP粘包问题解析与解决
一.粘包分析 作者本人在写一个FTP项目时,在文件的上传下载模块遇到了粘包问题.在网上找了一些解决办法,感觉对我情况都不好用,因此自己想了个比较好的解决办法,提供参考 1.1 粘包现象 在客户端与服务 ...
- socket粘包现象加解决办法
socket粘包现象分析与解决方案 简单远程执行命令程序开发(内容回顾) res = subprocess.Popen(cmd.decode('utf-8'),shell=True,stderr=su ...
- 2、粘包现象(struct模块)
昨天我们所做的套接字是有漏洞的,它会出现粘包现象,没有发现这个问题的我们今天会进行演示.今天也会稍微讲解一下基于udp的套接字. 一.基于udp的套接字 udp是无链接的,先启动哪一端都不会报错 ud ...
- Python网络编程(2)-粘包现象及socketserver模块实现TCP并发
1. 基于Tcp的远程调用命令实现 很多人应该都使用过Xshell工具,这是一个远程连接工具,通过上面的知识,就可以模拟出Xshell远程连接服务器并调用命令的功能. Tcp服务端代码如下: impo ...
- python之路--subprocess,粘包现象与解决办法,缓冲区
一. subprocess 的简单用法 import subprocess sub_obj = subprocess.Popen( 'dir', #系统指令 shell=True, #固定方法 std ...
- 29、粘包现象(struct模块)
昨天我们所做的套接字是有漏洞的,它会出现粘包现象,没有发现这个问题的我们今天会进行演示.今天也会稍微讲解一下基于udp的套接字. 本篇导航: 基于udp的套接字 粘包现象 粘包 解决粘包方法 stru ...
随机推荐
- MySQL修改版本号教程
处理扫描器扫出的漏洞,基本有四种方法:一是升级软件包到新版本(包括打补丁和整个替换升级),二是修改banner配置项(包括禁用banner和修改banner内容),三是添加白名单(包括主机防火墙和软件 ...
- date命令说明
基本使用格式: date [-d "time-to-display"] +"format-to-display" -d指定要显示的时间,如果不指定默认为当前时间 ...
- 转: Linux mount/unmount命令
https://blog.csdn.net/okhymok/article/details/76616892 楼主具体哪里转的 我不清楚 好像没看到原始出处 开机自动挂载 如果我们想实现开机自动挂载某 ...
- C#如何通过反射调用类下的方法
首先模拟一个mvc的项目,创建一个业务类(HomeService),在类下创建3个方法 public class HomeService { /// <summary> /// 无参方法 ...
- pl/sql 如何将Excel文件数据导入oracle的数据表?
1.准备导入数据的excel文件 注意:excel列名和数据表列名必须相同,excel文件sheet2和sheet3可以删除 1)excel文件格式 2)数据表格式 2.打开pl/sql ,找到工具- ...
- oracle中如何创建表的自增ID(通过序列)
1.什么是序列呢? 序列是一数据库对象,利用它可生成唯一的整数.一般使用序列自动地生成主码值.一个序列的值是由特别的Oracle程序自动生成,因而序列避免了在运用层实现序列而引起的性能瓶颈. Orac ...
- js如何比较两个日期之间相差数(天、时、分、秒)
首先,我们模拟一个例子 引入js文件 <script type="text/javascript" src="jquery.min.js">< ...
- python 学习笔记 字符串和编码
字符编码:因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理,最早的计算机在设计时采用8个比特(bit)作为一个字节 (byte),所以,一个字节能表示的最大的整数是255(二进 ...
- java⑧
1.switch的表达式取值: byte short int char Enum(枚举) jdk1.7版本以上支持 String类型 2. break: 01.代表跳出当前方法体!跳出 ...
- 《Python》模块和包
一.模块 1.什么是模块: 一个模块就是一个包含了Python定义和声明的文件,文件名就是模块名字加上.py的后缀. 但其实import加载的模块分为四个通用类别: 1.使用Python编写的代码(. ...