目录
1 网络编程基础
当今网络基本上都是使用TCP/IP协议进行通讯的。任何应用,比如浏览网页,微信,支付宝,抖音等都是通过TCP/IP协议进行通讯的。
TCP/IP协议就是一种数据传输方案。
在基于Python 3的网络编程中,需要掌握一些基本概念和模块。以下是一些重要的内容:
1.1 Socket 编程
Python 3提供了多种库来帮助进行网络编程。最基本的库是socket,它提供了标准的BSD套接字接口,并且可以用来创建客户端和服务器。通过使用socket库,可以进行底层网络通信。涉及的核心概念包括:
套接字类型(TCP / IP 套接字、UDP 套接字等)
套接字函数(如socket(), connect(), bind(), listen(), accept(), send(), recv()等)
客户端和服务器建立连接的过程
网络地址和端口号
非阻塞套接字和超时设置
套接字选项
使用with上下文管理器自动关闭套接字
通过socket编程接口进行信息传输可以按照如下图:
我们通过requests库发送HTTP请求消息,其实resquests库底层也是使用socket编程接口。
1.2 TCP 和 UDP 的使用
了解TCP(面向连接的协议)和UDP(无连接的协议)之间的差异至关重要,并学习什么时候使用它们。
TCP常用于要求高可靠性的应用,如网页浏览、文件传输、电子邮件等。
UDP常用于要求高性能和实时通信的应用,如视频流、在线游戏等。
1.3 高级网络模块
除了底层的sockets之外,Python还提供了更高级别的网络相关的模块:
http.client:用于创建HTTP客户端。
http.server:包含一个简单的HTTP服务器类。
urllib.request:用于打开和读取URLs,常用于HTTP请求。
ftplib:用于FTP传输。
smtplib:用于发送电子邮件。
ssl:用于在套接字上提供TLS/SSL安全性。
1.4 并发编程
当您创建网络服务器时,您通常需要同时处理多个客户端。这涉及到并发编程的概念,可以使用多线程、多进程或异步IO(例如asyncio模块)来实现。
线程(threading模块):可以为每个客户端创建一个新线程。
进程(multiprocessing模块):可以为每个客户端创建一个新进程。
异步IO(asyncio模块):使用单线程通过协程处理多个客户端连接和任务。
2 TCP协议的通讯及其代码展示
tcp进行通讯的双方,分为服务端和客户端。
tcp协议进行通讯的双方,最需要先建立一个虚拟连接,然后双方程序才能发送业务数据信息。
下面我们通过一个客户端程序和服务器端程序来展示这个通讯过程
2.1 客户端程序
from socket import *
IP="127.0.0.1"
SERVER_PORT=50000
BUFLEN=1024
#实例化一个socket对象,指明协议
dataSocket=socket(AF_INET,SOCK_STREAM)
# 连接服务器端socket
dataSocket.connect((IP,SERVER_PORT))
while True:
# 从终端读取用户输入的字符串
toSend=input(">>> ")
if toSend=="exit":
break
#发送消息,也要编码为bytes
dataSocket.send(toSend.encode())
# 等待接收服务端的消息
recved=dataSocket.recv(BUFLEN)
# 加入返回孔bytes,表示对方关闭了连接
if not recved:
break
# 打印读取的信息
print(recved.decode())
dataSocket.close()
2.2 服务器端代码
from socket import *
# 主机地址为0.0.0.0,表示绑定本机所有的网络接口IP地址。
# 等待客户端进行连接
IP="0.0.0.0"
# 端口号
PORT =50000
# 定义一次从socket缓冲区最多读取512个字节数据
BUFLEN=512
# AF_INET表示该socket网络层使用的IP协议
#参数SOCK_STREAM表示该socket传输层的tcp协议
listenSocket=socket(AF_INET,SOCK_STREAM)
# socket绑定地址和端口
listenSocket.bind((IP,PORT))
# 使socket处于监听状态,等待客户端的连接请求
# 参数5表示最多接收多少个等待连接的客户端
listenSocket.listen(5)
print(f"服务端启动通知,在{PORT}端口等待客户端连接...")
dataSocket,addr=listenSocket.accept()
print("接受一个客户端连接:",addr)
while True:
# 尝试读取对方发送的消息
# BUFLEN 指定从接受缓冲里最多读取多少字节
recved=dataSocket.recv(BUFLEN)
# 如果返回空bytes,表示对方关闭了连接
# 退出循环,结束消息收发
if not recved:
break
# 读取的字节数据是bytes类型,需要解码为字符串
info=recved.decode()
print(f"收到对方信息:{info}")
# 发送的数据类型必须是bytes,所以要进行编码
dataSocket.send(f"服务器接收到了信息{info}".encode())
# 服务端也调用close()关闭socket
dataSocket.close()
listenSocket.close()
2.3 结果展示
我们先运行服务器端程序,随后运动客户端程序,并在客户端代码的输入框中依次输入"hello world"、“next message”、“exit”
则在客户端运行结果展示如下:
在服务器端展示结果如下: