带你从入门到精通——Python(十三. 网络编程)

建议先阅读我之前的博客,掌握一定的Python前置知识后再阅读本文,链接如下:

带你从入门到精通——Python(一. 基础知识)-CSDN博客

带你从入门到精通——Python(二. 判断语句和循环语句)-CSDN博客

带你从入门到精通——Python(三. 函数基础)-CSDN博客

带你从入门到精通——Python(四. 五大容器一)-CSDN博客

带你从入门到精通——Python(五. 五大容器二)-CSDN博客

带你从入门到精通——Python(六. 函数进阶)-CSDN博客

带你从入门到精通——Python(七. 文件操作)-CSDN博客

带你从入门到精通——Python(八. 异常、模块和包)-CSDN博客

带你从入门到精通——Python(九. 面向对象一)-CSDN博客

带你从入门到精通——Python(十. 面向对象二)-CSDN博客

带你从入门到精通——Python(十一. 闭包、装饰器和深浅拷贝)-CSDN博客

带你从入门到精通——Python(十二. 迭代器、生成器和正则表达式)-CSDN博客

目录

十三. 网络编程

13.1 网络编程三要素

13.1.1 IP地址

13.1.2 端口

13.1.3 协议

13.2 socket套接字和编码转换

13.2.1 socket套接字

13.2.2 编码转换

13.3 TCP应用程序开发

13.3.1 TCP客户端程序开发

13.3.2 TCP服务端程序开发


十三. 网络编程

        网络是指将具有独立功能的多台计算机通过通信线路和通信设备连接起来,在网络管理软件及网络通信协议下,实现资源共享和信息传递的虚拟平台,而编写程序使计算机之间可以进行资源共享和信息传递就是网络编程

13.1 网络编程三要素

13.1.1 IP地址

        IP地址是分配给每个网络设备的一个数字标签,它能够标识网络中的唯一一台网络设备,我们可以通过IP地址能够找到网络中的某台网络设备,然后就可以跟这个网络设备进行通信。

        IP地址分为两类:

        IPv4地址是一个32位的二进制数,采用点分十进制表示法,即将32位地址分成4个8位的十进制数。

        IPv6地址是一个128位的二进制数,采用冒分十六进制表示法,即将128位地址分成8个16位的十进制数。

        Linux和mac系统可以使用ifconfig命令查看本地IP地址,windows系统可以使用ipconfig命令查看本地IP地址。

        使用ping + IP地址/域名命令可以测试本地网络是否连接。

13.1.2 端口

        端口是传输数据的通道,一台设备中每个运行中的程序都会分配一个端口,用于区分同一台设备上不同的程序,而且每一个端口都有一个对应的端口号,通过端口号即可查找到对应的端口。

        因此通信的一般过程为:通过IP地址在网络中找到对应的设备,通过端口号找到该设备对应的端口,然后通过端口把数据给对应的应用程序。

        端口号是一个16位的整数,取值范围从0到65535,根据端口号的不同范围,端口可以分为以下几类:

        知名端口:端口号范围是0到1023,这些端口被预先分配给一些常见的网络服务,例如:22号端口号用于SSH(Secure Shell Protocol,安全外壳协议)服务。

        注册端口:端口号范围是1024到49151,这些端口可以由用户或应用程序注册使用,例如MySQL数据库默认使用3306号端口。

        动态端口:端口号范围是49152到65535,这些端口通常是客户端程序在需要时进行动态分配。

13.1.3 协议

        协议是为了保证程序之间能够准确而有效地进行通信而指定的一系列数据传输规则,常用的协议有TCP协议和UDP协议,它们都是位于传输层的协议。

        OSI七层模型:应用层、表示层、会话层、传输层、网络层、数据链路层、物理层。

        TCP/IP五层参考模型:应用层、传输层、网络层、数据链路层、物理层。

        TCP协议(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流(将数据作为字节流进行传输)的传输层通信协议。

        面向连接是指通信双方必须先建立好连接才能进行数据传输,数据传输完成后,需要断开连接,以释放系统资源,而连接的建立也保证了数据的可靠传输。

        TCP协议的通信步骤:建立连接、数据传输、关闭连接。

        TCP协议在建立连接时需要三次握手

        客户端和服务端在握手前都是处于连接关闭(close)阶段,随后服务端首先进入监听(Listen)阶段,等待客户端连接,之后进入三次握手阶段。

        第一次握手:客户端向服务端发送一个SYN(synchronize)报文,该报文中包含:标志位SYN=1表示请求建立连接;Seq=x,x是一个随机生成的初始序列号。随后客户端进入SYN-SENT(同步发送)阶段。

        第二次握手:服务端收到客户端发送的SYN报文后,会结束监听阶段并向客户端发送一个SYN+ACK报文,随后服务端进入SYN-RECV(同步接收)阶段。SYN+ACK报文中包含:标志位SYN=1表示同意建立连接;标志位ACK=1表示确认收到客户端发送的SYN报文;Seq=y,y是服务端随机生成的一个初始序列号;Ack=x + 1作为确认号,表示发送端期望接收到的下一个报文的序列号,其中x是客户端的初始序列号。

        第三次握手:客户端收到服务端发送的SYN+ACK报文后,会结束SYN-SENT阶段并向服务端发送一个ACK报文,随后客户端进入ESTABLISHED(连接)阶段,ACK报文中包含:标志位ACK=1表示确认收到服务端发送的SYN+ACK报文;Seq=x + 1作为序列号;Ack=y + 1作为确认号。

        当服务端收到来自客户端发送的ACK报文后,会结束SYN-RECV阶段,进入ESTABLISHED阶段,完成三次握手过程。

        TCP协议在关闭连接时需要四次挥手

        客户端和服务端在挥手前都是处于连接状态,随后进入四次挥手阶段。

        第一次挥手:客户端向服务端发送FIN(finish)报文,该报文中包含:标志位FIN=1,表示请求关闭连接;Seq=u表示客户端的当前序列号。随后客户端进入FIN-WAIT-1阶段,即半关闭阶段,并且停止向服务端发送数据。

        第二次挥手:服务端收到客户端发送的FIN报文后,会结束ESTABLISHED阶段,进入CLOSE-WAIT阶段即半关闭状态,此时仍然可以向客户端发送数据,并向客户端发送ACK报文,该报文中包含:标志位ACK=1表示确认收到客户端发送的FIN报文;Seq=v表示服务端的当前序列号;Ack=u + 1作为确认号。客户端收到服务端发送的ACK报文后,会结束FIN-WAIT-1阶段,进入FIN-WAIT-2阶段。

        第三次挥手:在服务端在发出ACK报文后,服务器端会将剩余的待传数据传送给客户端,当服务端也完成数据传输后,会向客户端发送一个FIN报文,该报文中包含:标志位FIN表示同意关闭连接;标志位ACK=1表示确认收到客户端发送的FIN报文;Seq=w表示服务端的当前序列号;Ack=u + 1作为确认号。随后服务端会结束CLOSE-WAIT阶段,进入LAST-ACK阶段并且停止向客户端发送数据。

        第四次挥手:客户端接收到服务器的FIN报文后,会结束FIN-WAIT-2阶段,进入TIME-WAIT阶段,并向服务端发送一个ACK报文,该报文中包含:标志位ACK=1表示确认收到服务端发送的FIN报文;Seq=u + 1作为序列号;Ack=w + 1作为确认号。

        当服务端收到来自客户端发送的ACK报文后会结束LAST-ACK阶段并进入CLOES阶段,而客户端在等待一段时间后,结束TIME-WAIT阶段并进入CLOES阶段,完成四次挥手过程

        UDP(User Datagram Protocol)协议即用户数据报协议是一种无连接、不可靠的、面向数据报(将数据作为数据报进行传输)的传输层通信协议,UDP协议能够节省网络资源,并且有着更高的传输效率。

13.2 socket套接字和编码转换

13.2.1 socket套接字

        socket套接字是进程(运行中的应用程序)之间进行通信的一种约定或一种方式,通过socket套接字一台计算机可以接收其他计算机的数据,也可以向其他计算机发送数据。

13.2.2 编码转换

        在网络中,数据都是以二进制的形式进行传输的,所以在进行数据传输时,需要先将数据转换为二进制(bytes)数据类型。

        在Python中使用encode函数decode函数可以将字符串转换为二进制数据,示例如下:

# 参数encoding是指在编解码过程中使用的编码方案
s = '点赞关注收藏'
binary = s.encode('utf-8')
print(binary)
# b'\xe7\x82\xb9\xe8\xb5\x9e\xe5\x85\xb3\xe6\xb3\xa8\xe6\x94\xb6\xe8\x97\x8f'
print(binary.decode('utf-8'))
# 点赞关注收藏

13.3 TCP应用程序开发

        TCP应用程序开发分为TCP客户端程序开发TCP服务端程序开发

        客户端程序是指运行在用户设备上的程序,服务端程序是指运行在服务器设备上的程序,专门为客户端程序提供服务。

        TCP客户端程序及服务端程序整体的开发流程图如下:

13.3.1 TCP客户端程序开发

        TCP客户端程序开发的步骤为:

        1. 创建客户端套接字对象。

        2. 客户端连接服务端。

        3. 向服务端发送数据。

        4. 接收由服务端发送的数据。

        5. 关闭客户端套接字。

        示例如下:

import socket
# 1.创建客户端套接字对象,使用socket.socket()方法
# 第一个参数用于指定IP地址类型参数AF_INET表示使用ipv4协议
# 第二个参数用于指定传输协议类型参数SOCK_STREAM表示使用tcp协议
client_tcp_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2.客户端连接服务端,使用connect方法
# connect方法需要传入一个元组,用于指定连接的服务端地址
# 元组的第一个元素是字符串形式ip地址,第二个元素是整数形式端口号
client_tcp_sock.connect((ip, port))
# 3.向服务端发送数据,使用send方法
msg = input('请输入你要发送的内容\n')
client_tcp_sock.send(msg.encode('utf8'))
# 4.接收由服务端发送的数据,使用recv方法
# 参数1024表示TCP客户端套接字最多接收1024字节的数据
date = client_tcp_sock.recv(1024)
print(f"来自服务器的回复是:{date.decode('utf8')}")
# 5.关闭客户端套接字,使用close方法
client_tcp_sock.close()

13.3.2 TCP服务端程序开发

        TCP服务端程序开发的步骤为:

        1. 创建服务端套接字对象。

        2. 绑定IP和端口号。

        3. 开始监听。

        4. 等待来自客户端的连接请求。

        5. 接收由客户端发送的数据。

        6. 向客户端发送数据。

        7. 关闭服务端套接字。

        示例如下:

import socket
# 1.创建服务端套接字对象,该套接字被称为被动套接字,只负责接收客户端的连接请求,不能收发消息
server_tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2.绑定IP地址和端口号,服务器可以监听该IP地址和端口号上的连接请求
# 如果ip='',则默认使用本地ip地址
server_tcp_socket.bind((ip, port))
# 3.开始监听连接请求,参数5表示监听队列的最大长度,即等待被accept的连接请求队列的最大长度。
server_tcp_socket.listen(5)
# 4. 等待来自客户端的连接请求,当监听到客户端的连接请求时,会接收该请求并返回一个元组
# 元组中第一个元素是已经与客户端建立连接的新的套接字对象,用于与客户端收发消息
# 第二个元素是客户端的IP地址和端口号
connect_tcp_socket, addr = server_tcp_socket.accept()
# 5. 接收由客户端发送的数据
date = connect_tcp_socket.recv(1024)
print(date.decode('utf8'))
# 6. 向客户端发送数据
msg = input('请输入你要回复的内容\n')
connect_tcp_socket.send(msg.encode('utf8'))
# 7. 关闭客户端套接字
connect_tcp_socket.close()
server_tcp_socket.close()

        当客户端和服务端的TCP连接在断开时,需要进行四次挥手过程,在服务端处于CLOSE阶段时,客户端可能还处于TIME-WAIT阶段,需要等待一段时间才会进入CLOSE阶段,当客户端和服务端都进入CLOSE阶段时,服务端套接字绑定的端口才会被释放,为了避免客户端TIME-WAIT阶段的影响,使得只要服务端处于CLOSE阶段就可以释放服务端套接字绑定的端口,以便重启服务端后再次绑定该端口,可以在创建服务端套接字时添加使用以下代码:

server_tcp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)

        上述setsockopt方法用于设置套接字选项,第一个参数用于指定选项级别,socket.SOL_SOCKET表示设置的是通用的套接字级别的选项,第二个参数用于指定选项名,socket.SO_REUSEADDR表示设置的是端口复用选项,第三个参数表示选项的值,True表示启用该选项。

        注意:当客户端/服务端的套接字如果在未发送数据前提前被关闭,服务端/客户端的接收到一个长度为0的二进制空字符串''。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值