Python(二十七)通信原理
通信简单来说指的就是信息的传递。官方一点的话,人与人,或人与自然之间,通过某种行为或媒介,进行的信息交流与传递,叫做通信。身处信息时代的我们,对通信的需求和依赖变得前所未有的强烈,所以掌握最基本的通信原理知识是我们每个人都应该做的。
下文写的传输模型和TCP协议,对大家了解最基本的通信原理知识很有帮助,所以不妨花点时间看一看。
1. 传输模型
1.1. 基本认知
1.2 层次模型
各层说明
1.2.1 应用层
有网却无法登录网页,可以使用清除DNS缓存的方式。
1.2.2. 传输层
网络协议是指通信双方就通信如何进行所必须共同遵守的约定和通信规则的集合。在网络上通信的双方只有遵守相同的协议,才能正确地交流信息。
1.2.2.1. TCP
- 通过三次握手协议建立稳定链接
2.应用数据分割成最合适的数据块发送
3.链接可靠,不易出现乱序、丢失等现象
4.连接和检验等都需要花不少时间,效率因此会降低
1.2.2.2. UDP
1.一次性发送所有数据,无需建立连接
2.服务器可以同时发送给多个客户机
3.没有检验,容易会出现信息丢失
4.消耗资源小,处理速度快
1.2.2.3. 端口
当同时多个程序使用网络时,为了保证信息发送到正确的地方,增加了端口,不同的软件使用不同的端口,虽然使用同一个网络,但是因为端口不一样,也能保证信息发送给正确的人。端口号的范围从0到65535 (2^16-1),比如用于浏览网页服务的80端口,用于FTP服务的21端口等。ip地址用于区分不同的主机,而端口号是用于区分一个主机下的不同网络服务。
1.2.3. 网络层
1.2.3.1. IPV4和IPV6
ipv4是第一个被广泛应用的ip,IP是TCP/IP协议族中网络层的协议,是TCP/IP协议族的核心协议。
ipv4的地址长度规定为32位,分为四段,每段8位且以点隔开,并以十进制形式表示,故每段的数值范围为0~255,即最小的为0.0.0.0,最大为255.255.255.255。
由于ipv4位数使得其地址资源己被分配完,故产生了ipv6。
ipv6的长度是ipv4的四倍,以十六进制形式表示,其被分为8段,每段以冒号隔开。
其中地址块127.0.0.1被保留作环回通信用,0.0.0.0为任意使用。
2. TCP协议
2.1. 三次握手
第一步:客户端发送SYN报文给服务器端,进入SYN_SEND状态。
第二步:服务器端收到SYN报文,回应一个SYN ACK报文,进入SYN_RECV状态。
第三步:客户端收到服务器端的SYN报文,回应一个ACK报文,进入Established状态。
【注】先开启服务端
三次握手完成,TCP客户端和服务器端成功地建立连接,可以开始传输数据了。过程如下图所示:
三次握手
2.2. 传输数据
短连接(类似于打字聊天):
建立连接--数据传输--关闭连接...建立连接--数据传输--关闭连接
长连接(类似于语音、视频通话):
建立连接--数据传输...(保持连接)...数据传输--关闭连接
2.3. 四次挥手
第一步:先由客户端向服务器端发送一个FIN,请求关闭数据传输。
第二步:当服务器接收到客户端的FIN时,向客户端发送一个ACK,其中ack的值等于FIN+SEQ。
第三步:然后服务器向客户端发送一个FIN,告诉客户端应用程序关闭。
第四步:当客户端收到服务器端的FIN时,回复一个ACK给服务器端。其中ack的值等于FIN+SEQ。
【注】先关闭客户端
四次挥手
2.4. 代码演示
紫红背景色的为Oracle VM VirtualBox(充当服务端)
黑背景色的为MobaXterm(充当客户端)
import socket
:导入socket模块。
server = socket.socket()
:创建一个socket对象,命名为服务器。
server
:查看变量server,fd为文件描述符(唯一标识一个socket);AF_INET表示ipv4,AF_INET6表示ipv6;SOCK_STREAM表示TCP协议,SOCK_DGRAM表示UDP协议;protocol协议通常是0,tcp/ip协议簇;laddr还没有绑定,所以都是0。
server.bind('127.0.0.1',8989)
:绑定端口,注意这里填入的是元组。
server.listen(10)
:设置最大监听数,最大连接量。
import socket
:导入socket模块。
client = socket.socket()
:创建一个socket对象,命名为客户端。
client.connect(('127.0.0.1',8989))
:连接服务器端口,注意这里填入的是元组。
client.send(b'hello')
:客户端发送字节类型数据给服务器,返回字节数。
result = server.accept()
与客户端创建对等套接字。
conn.,address = result
:元组拆包。
address
:客户端地址。
conn.recv(1024)
:服务器接收字节数据,最大接收长度为1024。
conn.send(b'ok ok')
:服务器发送字节类型数据给客户端,返回字节数。
client.recv(5)
:客户端接收字节数据,最大接收长度为5。
client.send(b'陈宏好帅')
:未编码成字节类型数据,无法发送,会报错。所以需要修改为st = '陈宏好帅'.encode('utf -8')
,然后再client.send(st)
。
服务器端接收时需要先接收客户端编码的数据再解码,所以先写成a = conn.recv(1024)
,然后再a.decode('utf-8')
:
操作完毕以后,按照下方顺序关闭:
client.close()
:客户端先关闭
conn.close()
:服务端关闭套接字
server.close()
:服务端后关闭
quit()
:即可退出Python命令行模式
文章到这里就结束了!希望大家能多多支持Python(系列)!六个月带大家学会Python,私聊我,可以问关于本文章的问题!以后每天都会发布新的文章,喜欢的点点关注!一个陪伴你学习Python的新青年!不管多忙都会更新下去,一起加油!
Editor:Lonelyroots