[TOC]
本项目是一个只有4份Python代码的开源小工程,用来学习基于TCP的套接字通信包,可以自定义通信协议,处理分包和粘包。内置一个服务端和客户端程序,也有对应的博客讲解代码。整个工程基本基于良好的面向对象思想,代码注释清晰简洁。
这个小项目共有4份代码,各自作用如下:
代码模块 | 主要功能 |
---|---|
MsgProtol.py | 网络通信的消息协议,提供消息打包和解包功能 |
ServerSocket.py | 提供基于Python程序的服务端通信功能 |
ClientSocket.py | 提供基于Python程序的客户端通信功能 |
testPack.py | 本模块用来设计测试服务端处理分包和粘包的能力 |
基于TCP的套接字通信是深入学习Python程序的必备技能之一,套接字不仅可以用于网络编程,在本地不同进程之间的通信、不同编程语言的程序通信中也应用十分广泛。 本篇文章是在之前了解套接字编程接口的基础上进一步扩展,写出一套真正可用于实际程序通信的代码。
本项目会集中研究套接字通信中的分包和粘包问题、自定义通信协议的方法,方便入门套接字的同学进阶。
如果您不了解基础的基于Python的TCP套接字接口,可以先简单阅读我的博客**Python编程——基于TCP的套接字简单通信,如果觉得对您有帮助,欢迎收藏、点赞。**
完整的项目开源信息如下:
MNetSocket-Python | 基于Python的网络通信包 |
---|---|
开发者 | MRL Liu |
编程语言 | Python3 |
项目描述 | 基于TCP的套接字通信包,可以自定义通信协议,处理分包和粘包 |
博客 | https://blog.csdn.net/qq_41959920/article/details/115380403 |
GitHub | https://github.com/MagicDeveloperDRL/MNetSocket-Python |
参考博客 | https://blog.csdn.net/yannanxiu/article/details/52096465 |
众所周知,套接字是主流语言提供的用于进行网络进程通信的程序接口,其中最常见的是基于TCP协议的套接字编程,基于TCP协议的套接字可以保证:
**可靠传播。**在一般情况下,数据传输过程中数据不会发生丢失,并且数据发送和接收的顺序不会改变,即我发送一个“Hello”和“World”,对方一定会按顺序先后收到“Hello”和“World”。
**数据可靠。**在一般情况下,数据传输过程中无论数据包被如何组合拆分等,都不会添加与发送信息无关的无效信息,即数据不会被污染,按照指定编码方式进行解码即可还原原来的信息。
但是在实际进行TCP编程的过程中,如果使用原生的套接字接口,在处理消息通信时,需要处理以下两个典型问题:
TCP是以段(Segment)为单位发送数据的,建立TCP链接后,有一个最大消息长度(MSS)。如果应用层数据包超过MSS,就会把应用层数据包拆分,分成两个段来发送。这个时候接收端的应用层就要拼接这两个TCP包,才能正确处理数据。
简单理解,分包现象就是一次传输的数据过多时,TCP协议会自动将本次的数据拆分成多个消息包进行发送。
例如,发送方发送字符串”helloworld”,接收方却接收到了两个字符串”hello”和”world”。
在某些特殊环境下,TCP为了提高网络的利用率,会使用一个叫做Nagle的算法。该算法是指,发送端即使有要发送的数据,如果很少的话,会延迟发送。如果应用层给TCP传送数据很快的话,就会把两个应用层数据包“粘”在一起,TCP最后只发一个TCP数据包给接收端。
简单理解,粘包现象就是当网络繁忙时,TCP协议会将多份小的消息包打包成一个消息包进行发送。
例如,发送方发送两个字符串”hello”+”world”,接收方却一次性接收到了”helloworld”。
TCP套接字可以提供基本的字符串类型的信息传输,但是字符串可以代表什么含义,怎么解释它需要开发者来自定义。更重要的是,为了解决分包和粘包问题,我们也必须自定义一个简单的通信协议。
通信协议听起来很高大上,其实本质上就是发送方和接收方达成的约定,对每个完整的消息包格式做出规定,接收数据时按照这个格式进行检查,从而得到一个个正确的消息包。
最简单的消息格式就是我们在消息正文的前方加入一个固定长度的数字表示消息正文的长度,这样就可以基本解决分包和粘包问题。
但是为了之后可以判断我们的消息类型,也为了便于设计客户端和服务端,我们这里稍微复杂一点,即本文定义的消息格式如下:
消息头 | 消息正文 | ||
---|---|---|---|
正文长度(bodySize) | 指令类型(cmd) | 是否回复(recv) | 正文 |
无符号32位整型变量 | 无符号32位整型变量 | 无符号32位整型变量 | —— |
4字节 | 4字节 | 4字节 | —— |
本人博客会详细介绍如何实现上述设计。