立即学习:https://edu.csdn.net/course/play/24458/296241?utm_source=blogtoedu

 1.send和recv底层分析

1)不管是recv还是send都不是直接接收对方数据或者发送给对方数据,而是对自己的操作系统内存进行操作;

2)客户端与服务端并不是一个send对于一个recv;

3)send过程分析(此处以客户端向服务端发送数据为例):

#1.客户端将数据发送给自己的操作系统,即将数据给操作系统内存,这样就算是结束了send这个命令,而至于怎么将数据发送给服务端由客户端的操作系统决定;

#2.send需要经历的阶段:产生数据——将数据copy给客户端自己的操作系统内存

4)recv过程分析(以服务端接收客户端数据为例)

#1.服务端首先是等待客户端的数据,然后接收数据即可

#2.recv经历的阶段:wait data(耗时较长)——copy data(首先是客户端的操作系统内存的数据通过网关发送给服务端的操作系统内存,然后再由服务端的程序从自身的操作系统内存中copy data,再进行执行,这就完成recv的过程)

2.粘包产生的原因:由TCP协议中的优化算法nagle算法决定的。TCP协议存在的问题,在UDP协议中不会出现这种问题

1)产生粘包的条件:数据小且两次或多次发送数据的间隔小的情况下会产生粘包现象,所以使用TCP协议不是一定会发生粘包,只有满足条件才会

2)在TCP协议中,send是一条一条消息地发送数据,而recv却可以一次性接收多条消息发送的数据,即接收到的数据是一个整体,因为在时间间隔较短的时间内发送的小数据会在客户端的操作系统内存中会被合并成一个数据包,再发送给服务端的操作系统内存,因此无法判断出哪些数据是哪条消息的,TCP时面向流的

3)TCP是面向流的,为了减少IO传输

的次数进而增加传输数据的效率,采用了nagle算法,将间隔时间短的小数据合并成一个大的数据块进行接收处理,然后将处理后的大的数据块返回给客户端,而客户端无法识别出哪些数据是哪条信息的,故产生了粘包!

4)在客户端粘包的情况,在客户端时间间隔短的情况下发送两次数据,导致客户端发送的数据产生粘包现象

#客户端产生粘包的情况'''
客户端
'''
import socket
phone = socket.socket((socket.AF_INET,socket.SOCK_STREAM))
phone.connect(('127.0.0.1',8080))
phone.send('hello')
phone.send('world')'''
服务端
'''
import socket
phone = socket.socket((socket.AF_INET,socket.SOCK_STREAM))
phone.bind(('127.0.0.1',8080))
conn,client  = phone.accept()res1 = conn.recv(1024)
#b'helloworld'
print('第一次接收的数据:',res1)res2 = phone.recv(1024)
#b''
print('第二次接收的数据:',res2)#客户端不存在粘包的现象,只需要在客户端的两次send之间加入一个time.sleep(2)即可,即破坏粘包产生的条件之一:间隔时间短的情况下发送多次数据

4)服务端产生粘包现象

#客户端
......
phone.send('hello'.encode('utf-8'))
time.sleep(5)
phone.send('world'.encode('utf-8'))
......#服务端
......
res1 = conn.recv(1)
#b'h'
print('第一次接收的数据',res1)
time.sleep(6)#服务器端比客户端多睡一秒钟,因此上一次的发送的未接收的数据‘ello’会和这次发送的world在服务器端的操作系统内存中合并在一起
res2 = conn.recv(1024)
#b'elloworld'
print('第二次接收的数据:',res2)

注:上述只是便于理解才用time.sleep()来解决粘包,实际上是非常不支持这样来解决粘包问题

学习笔记(11):Python网络编程并发编程-粘包底层原理分析相关推荐

  1. 学习笔记(19):Python网络编程并发编程-互斥锁

    立即学习:https://edu.csdn.net/course/play/24458/296430?utm_source=blogtoedu 1.互斥锁: 多进程间的内存是相互隔离的,因此其数据也是 ...

  2. 学习笔记(34):Python网络编程并发编程-异步调用与回调机制

    立即学习:https://edu.csdn.net/course/play/24458/296452?utm_source=blogtoedu 1.知识点:(详细见代码注释) 1)同步调用: res1 ...

  3. 学习笔记(33):Python网络编程并发编程-进程池线程池

    立即学习:https://edu.csdn.net/course/play/24458/296451?utm_source=blogtoedu 进程池与线程池: 一般应用在网站上,进程池或线程池最大的 ...

  4. 学习笔记(28):Python网络编程并发编程-死锁与递归锁

    立即学习:https://edu.csdn.net/course/play/24458/296445?utm_source=blogtoedu 1.死锁(Lock()的局限性) 知识点:Lock()只 ...

  5. 学习笔记(18):Python网络编程并发编程-守护进程

    立即学习:https://edu.csdn.net/course/play/24458/296429?utm_source=blogtoedu 守护进程(了解) 1.概念:守护进程是主进程在创建子进程 ...

  6. 学习笔记(10):Python网络编程并发编程-粘包现象

    立即学习:https://edu.csdn.net/course/play/24458/296240?utm_source=blogtoedu 粘包现象:服务器接收到客户端的命令后,进行执行得到结果后 ...

  7. 学习笔记(09):Python网络编程并发编程-模拟ssh远程执行命令-代码实现

    立即学习:https://edu.csdn.net/course/play/24458/296239?utm_source=blogtoedu 1.服务器端:接收客户端发送的命令,subprocess ...

  8. 学习笔记(12):Python网络编程并发编程-解决粘包问题-简单版本

    立即学习:https://edu.csdn.net/course/play/24458/296243?utm_source=blogtoedu 粘包现象的解决:简单版 1.思路:       在服务器 ...

  9. 学习笔记(08):Python网络编程并发编程-实现服务端可以对多个客户端提供服务

    立即学习:https://edu.csdn.net/course/play/24458/296237?utm_source=blogtoedu 链接循环,一个服务器服务多个客户端, 思路1:服务器一个 ...

最新文章

  1. glusterfs初步实践一(类似NFS)
  2. React.js核心原理实现:首次渲染机制
  3. js 获取vue组件html_vue.js中怎么引入组件?
  4. 从程序员到上市公司合伙人,怎么少踩坑?
  5. ERRORS:*: (auth.E003) ‘User.username‘ must be unique because it is named as the ‘USERNAME_FIELD
  6. Android学习笔记——保存数据到SQL数据库中(Saving Data in SQL Databases)
  7. Android上传文件至服务器
  8. 【Java虚拟机】运行时数据区
  9. 如何在 Ubuntu 14.04 里面配置 chroot 环境
  10. mysql 处理文件函数_mysql的字符串处理函数
  11. 微信AES-128-CBC加密解密
  12. DSP6678核间通信
  13. 二进制 八进制 十进制 转换
  14. 视频编辑转换 ViscomSoft SDK ActiveX 19.0
  15. Ubuntu和win10系统(N卡)
  16. Js出库入库数量变化
  17. 一步步教你新电脑如何分区教程
  18. demonstration记忆_雅思分类词汇背诵记忆:教育2
  19. Nacos服务注册与发现源码(一)之gRPC协议的实例注册
  20. Android ListView完全解析

热门文章

  1. POJ 1637 Sightseeing tour 混合图欧拉回路存在性判断
  2. 当查找名字的时候通过外围作用域向外查找(如何理解)
  3. TCP/IP(二):IP协议
  4. Vue项目中Table设置 render 函数
  5. 数据仓库基础(二)ETL
  6. 六、利用frp穿透连接内网的linx系统和windows系统
  7. JSP慕课网阶段用户登录小例子(不用数据库)
  8. JS脚本显示当前日期+星期几[转]
  9. js 字符ascii码转换函数
  10. springboot---基本模块详解