首先,来看一个代码,使用TCP协议,发送端发送一句话,接收端接收并显示,运行完全正常。

接下来,把客户端代码稍微修改一下,连续发送多个数据,

按照正常的想法,在服务端输出的信息应该是分为多行的,这样才和客户端对应。然后运行结果并不是想象的那样子。从运行结果来看,应该是服务端把收到的数据放在缓冲区里了,有了足够多的数据之后才处理。

recv()方法的参数用来确定一次从缓冲区中最多读取多少字节的数据,为了清楚其含义,稍微修改代码,

学过计算机网络的朋友一般会听说过Nagle算法。在使用TCP协议进行传输时,会在有效数据前面增加大量头部信息来保证可靠传输,如果发送的有效数据非常短,增加头部带来的额外开销就非常大。为了优化和减少带宽占用,避免大量小包堵塞网络,发送端会在发送大量小包时积累一定数量的数据之后组成一个大包晚些时间再发送(粘包),在发送大包时会根据情况切分成多个包发送(断包)。同理,接收端在接收大包时有可能会进行截断以免缓冲区放不下(断包),接收连续多个小包时会在缓冲区暂存一段时间合并成大包再处理(粘包),也就是所谓Nagle算法。

Nagle算法的优化在大部分情况下都是非常好的,但也会给接收端带来一定的麻烦,必须要正确识别和读取一个完整的包之后再处理,以免后面的功能代码无法正常工作。这需要额外写更多代码来正确读取一个完整的包,例如发送端先告知接收端要发送的数据长度,或者双方约定好数据的起始标记和结束标记。

如果到网上(甚至一些书上)搜索资料,会说禁用Nagle算法就可以了,也就是设置套接字属性启用TCP_NODELAY,非常简单。既然如此,那就赶紧用起来吧。

在Python中,标准库socket封装了套接字编程需要的功能,创建套接字之后可以使用setsockopt来设置当前套接字的各种属性,其中就包括禁用断包和粘包的延迟从而禁用Nagle算法。

结果显示,这个选项根本没有起作用。那会不会是需要在通信双方都启用TCP_NODELAY呢?于是把客户端也设置一下,重新运行程序,发现还是没有用。

继续查资料,会有人说,要真正禁用Nagle算法只把TCP_NODELAY设置为True是不够的,还需要把接收端的接收缓冲区大小设置为0才行。原来是这样啊,那就赶紧修改代码吧,事实证明还是没有用的。

也有资料显示,通信双方需要协商一下,为避免接收端粘包时误把下一条信息的一部分合并到当前信息尾部,可以协商一个起始标记和结束标记,接收端根据接收的信息来查找这些标记并进行正确的切分。这听起来是个好思路,但真正用起来的时候难度还是很大的,感兴趣的朋友可以尝试一下。

再一个思路也是在传输大量数据时经常使用的,就是发送端首先告诉对方接下来要发送的数据长度,然后再发送实际数据。接收端首先接收一个整数来表示接下来要接收的数据总长度,然后使用循环来接收数据,直到恰好接收完刚才约定的数据长度为止。为了避免发生粘包,接收端需要动态调整缓冲区大小来控制每次接收的数据,防止接收多了。

现在的问题就是如何确保把数据长度有效传递给对方了,可以使用Python标准库struct把整数序列化为字节串发送给对方,而这个字节串的长度固定为4,这样的话,接收端使用recv(4)接收到这个字节串再反序列化为整数就可以了。

上面这个思路是完美的,也是优先推荐使用的,但是需要在编写程序之前就确定好代码思路和框架。

如果在编写代码时没有遵循这个思路,都是直接进行发送和接收导致了粘包的发生,又不想对代码进行大幅度的修改,可以考虑在发送完一段完整意义的数据之后加一个很小的延时,这样接收端不会等待更多数据后一起处理。虽然这样可以实现功能,但这个小延时的积累是非常大的,非常不适合服务端代码的设计,要慎重使用。

在本文最后,给出一个多线程版本的Socket程序,供参考。

温馨提示

关注本公众号“Python小屋”,通过菜单“最新资源”==>“历史文章”可以快速查看分专题的1000篇技术文章列表(可根据关键字在页面上搜索感兴趣的文章),通过“最新资源”==>“微课专区”可以免费观看500节Python微课,通过“最新资源”==>“培训动态”可以查看近期Python培训安排,通过“最新资源”==>“教学资源”可以查看Python教学资源。

---董付国老师Python系列图书---

友情提示:不建议购买太多,最好先通过京东、当当、天猫查阅图书了解目录和侧重点,然后再选择购买适合自己的书。

(1)《Python程序设计(第2版)》(ISBN:978-7-302-43651-5),清华大学出版社,2016年8月出版,2019年度清华大学出版社畅销图书

(2)《Python可以这样学》(ISBN:978-7-302-45646-9),清华大学出版社,2017年2月

(3)《Python程序设计基础(第2版)》(ISBN:978-7-302-49056-2)清华大学出版社,2018年1月出版,2019年度清华大学出版社畅销图书

(4)《中学生可以这样学Python》(ISBN:978-7-302-48039-6)清华大学出版社

(5)《Python程序设计开发宝典》(ISBN:978-7-302-47210-0)清华大学出版社,2018年10月

(6)《玩转Python轻松过二级》(ISBN:978-7-302-49916-9)清华大学出版社,2018年5月

(7)《Python程序设计基础与应用》(ISBN:978-7-111-60617-8),机械工业出版社,2018年9月

(8)《Python程序设计实验指导书》(ISBN:9787302525790),清华大学出版社,2019年4月

(9)《Python编程基础与案例集锦(中学版)》(ISBN:978-7-121-35539-4),电子工业出版社,2019年4月

(10)《大数据的Python基础》(ISBN:978-7-111-62455-4),机械工业出版社,预计2019年5月出版

(11)译作《Python程序设计》,机械工业出版社(华章),2018年11月出版

(12)繁体版《Python也可以这样学》,台湾博硕文化股份有限公司,2017年10月出版,本书为《Python可以这样学》在台湾发行的繁体版,两本书内容一样,不建议重复购买。

(13)《Python程序设计实例教程》(ISBN:978-7-111-63198-9),机械工业出版社

(14)《Python数据分析、挖掘与可视化》(ISBN:978-7-115-52361-7),人民邮电出版社,2019年12月

Python相关课程教材选用参考与建议

董付国老师Python在线课程资源使用方法

董付国老师6本Python教材PDF版免费阅读

《Python数据分析、挖掘与可视化》前3章书稿PDF免费阅读

《Python程序设计基础与应用》前3章书稿PDF免费阅读

号外号外--Python小屋刷题神器上线啦

《中学生可以这样学Python》84节微课免费观看地址

相关阅读

Python实现多进程/多线程同时下载单个文件

Python 3.8实现支持断点续传的网络文件下载功能

Python+winreg+netifaces查看网络接口信息

Python自动接收微信群消息并推送相应的公众号文章

Python+psutil获取本机所有联网的应用程序信息

Python多线程编程的一个掉进去不太容易爬出来的坑

Python+socket+多线程实现同时应答多客户端的自助聊天机器人

Python实现机房管理软件的文件分发功能

技术要点|Python监控学生端电脑屏幕自动识别学习状态

Python多线程与Socket编程综合案例:素数

Python批量下载电子邮件附件并汇总合并Excel文件

Python监视电子邮箱并提示收到新邮件

Python版课堂管理系统中使用UDP广播远程关闭客户端程序思路与源码

使用Python实现电子邮件群发功能

基于Python的电子教室软件中远程关机功能的原理与实现

Python获取本机所有IP地址

Python实现局域网内屏幕广播的技术要点分析

使用Python开发SQLite代理服务器

Python获取局域网内所有机器IP地址与网卡MAC地址

Python获取本机所有网卡的MAC地址

Python+flask+flask-email发送带附件的电子邮件

Python使用UDP协议打造在线时间服务器

使用Python开发会聊天的智能小机器人

Python使用TCP协议编写会聊天的小机器人

Python实现本机网络流量监视器

Python使用UDP广播实现服务器自动发现

Python网页注入挂马

Python监视域名对应IP地址变化情况

完美解决Python套接字编程时TCP断包与粘包问题相关推荐

  1. Python 套接字编程

    Python 套接字编程学习历程 1.什么是socket? Socket中文译作:套接字,socket是来建立'通信'的基础,建立连接,传输数据'通信端点'. 每一个套接字就是一组接口与端口的组合,用 ...

  2. python套接字编程_Python套接字编程(1)——socket模块与套接字编程

    在Python网络编程系列,我们主要学习以下内容: 5. 常见的Python异步编程框架 6. 协程在Python网络编程中的使用 本文介绍Python下的基本套接字编程,主要基于 socket 模块 ...

  3. 使用Python套接字编程的视频聊天应用

    在这场流行病中,我们正经历着大量的公司转向在线平台,并在家里开始伟大的倡议工作,但如果我们不能与团队联系起来,这怎么可能呢? 因此,为了解决这一挑战,公司开始使用软件,允许他们在摄像头和其他资源的帮助 ...

  4. python的socket编程接收浏览器上传的文件_使用python套接字编程将文件发送到浏览器...

    我正在尝试使用python(仅限于套接字编程)向客户机(浏览器:Chrome)发送一个文件(mp3).我的问题是文件被下载了,而不是在浏览器上进行流式传输.我不明白我哪里错了.请告诉我.在 另外,下载 ...

  5. 【网络编程】Socket套接字;UDP数据报套接字编程;TCP流套接字编程

    文章目录 1. 什么是网络编程 2. 网络编程中的基本概念 3. Socket套接字 4 UDP数据报套接字编程 4.1 客户端服务器交互流程 4.2 UDP版本的回显服务 4.3 英译汉服务 5. ...

  6. 计算机网络套接字编程实验-TCP多进程并发服务器程序与单进程客户端程序(简单回声)

    1.实验系列 ·Linux NAP-Linux网络应用编程系列 2.实验目的 ·理解多进程(Multiprocess)相关基本概念,理解父子进程之间的关系与差异,熟练掌握基于fork()的多进程编程模 ...

  7. python网络套接字_Python网络编程 Python套接字编程

    Python 提供了两个级别访问的网络服务. 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的全部方法. 高级别的网络服 ...

  8. python套接字编程_Python网络编程 Python套接字编程

    Python 提供了两个级别访问的网络服务. 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的全部方法. 高级别的网络服 ...

  9. 计算机网络套接字编程实验-TCP单进程循环服务器程序与单进程客户端程序(简单回声)

    1.实验系列 ·Linux NAP-Linux网络应用编程系列 2.实验目的 ·理解并掌握在程序运行时从命令行读取数据的C语言编程方法: ·理解并掌握基于命令参数设置并获取IP与Port的C语言编程方 ...

最新文章

  1. sqlconnection,sqlcommand,SqlDataAdapter ,ExecuteNonQuery,ExecuteScalar
  2. 数仓建模 项目_音乐数据项目火力全开,技能双倍提升!
  3. 解决MySQL删除外键时报错Error Code: 1091. Can‘t DROP ‘XXX‘; check that column/key exists
  4. 快速搭建Springboot项目的两种方式!!
  5. QGroundControl源码编译安装
  6. 【洛谷 P2764】 最小路径覆盖问题(最大流)
  7. 【图像增强】基于matlab PSO寻优ACE算法图像增强【含Matlab源码 088期】
  8. c语言最好的文本编辑器,【软件分享】两个小巧好用的C语言编辑器
  9. maya布料预设解析
  10. 中移动IM+MM 抢滩移动互联网
  11. OSChina 周三乱弹 ——祖传的程序员?????
  12. RGB图像点落入色度图上的算法
  13. 城通网盘文件过期自动提醒
  14. android购票日历,2017春运购票日历
  15. [附源码]Node.js计算机毕业设计大学生学科竞赛管理系统Express
  16. neso n810 i7 android 4.4,搭载64位英特尔芯 NESO N810 i7平板电脑发布
  17. 对抗样本生成方法论文阅读笔记
  18. 将word文档中的图片批量导出到文件夹中的办法
  19. PHP date() 和 strtotime() 使用详解
  20. 阿里天池大赛-工业蒸汽预测

热门文章

  1. Spring3.1.1+Jersey2.2+ehcache实现WebApp与服务器接口交互获取令牌及校验过程
  2. excel的ADO读取ORACLE,【VBA研究】利用ADO让普通人用excel读取oracle数据库表的通用办...
  3. java输出动物,求大神帮助输出为什么只有动物名,几条腿,怎么叫,没有汤姆猫叫等...
  4. 单机 mysql 复制_MySQL单机复制
  5. mysql数据完整性约束包括_MYSQL回顾(完整性约束相关)
  6. pcap java_java解析Pcap(io.pkts)
  7. java canvas 画圆_java – 如何在Android中通过canvas绘制圆?
  8. aes解密算法 java_AES算法实现Java和JS互通加解密
  9. linux主机查看CPU核数和主机型号
  10. 01 离散时间信号的时域表示