1. 预备知识:网络协议
1.1 什么是网络协议?
[!note] 网络协议(Protocol)是计算机网络中不同设备之间进行数据通信所必须遵循的规则和标准,它规定了数据的格式、传输顺序、速度以及如何处理错误等,协议是计算机网络通信的基础,没有网络协议,计算机之间就无法进行有效的数据交换
网络协议的作用主要体现在以下几个方面:
- 规范通信流程:确保数据在发送和接收过程中遵循一定的顺序和格式,避免出现混乱和错误。
- 保证可靠传输:通过协议中的差错控制机制,如校验和、确认应答和重传等,确保数据在传输过程中不被损坏或丢失。
- 支持多种应用:不同的网络协议可以支持各种不同的网络应用,如网页浏览、文件传输、电子邮件等。
- 实现互连互通:使不同厂商、不同类型的设备能够在同一网络中进行通信和协作。
网络协议类比——《计算机网络:自顶向下方法》" />
1.2 常用网络协议
常见的网络协议有很多,覆盖网页浏览、文件传输、数据传输、邮件系统等,以下是一些较重要的:
协议 | OSI层级 | 主要功能 | Python模块 | 核心能力 | 典型场景 |
---|---|---|---|---|---|
TCP | 传输层 | 可靠数据流传输 | socket | 创建TCP Socket,支持SOCK_STREAM 类型 | 文件传输、Web通信 |
UDP | 传输层 | 快速无连接传输 | socket | 创建UDP Socket,支持SOCK_DGRAM 类型 | 实时视频、DNS查询 |
HTTP | 应用层 | 客户端-服务端请求响应 | requests | requests 提供简洁API,支持Session/HTTPS | RESTful API交互 |
HTTPS | 应用层 | 加密的HTTP通信 | requests | 自动SSL证书验证,支持TLS 1.3 | 支付接口、敏感数据传输 |
SMTP | 应用层 | 邮件发送 | smtplib | 支持SMTP_SSL加密,可附加MIME内容 | 系统告警邮件 |
IMAP | 应用层 | 邮件接收与管理 | imaplib | 支持邮箱文件夹操作、邮件标记 | 邮件自动化处理 |
WebSocket | 应用层 | 全双工实时通信 | websockets | 异步支持,自动处理握手协议 | 在线聊天、股票行情 |
SSH | 应用层 | 加密远程访问 | paramiko | SFTP文件传输、命令执行,支持密钥认证 | 服务器运维 |
DNS | 应用层 | 域名解析 | dnspython | 支持多种记录类型查询(A/MX/NS) | 域名监控系统 |
FTP | 应用层 | 文件传输 | ftplib | 支持主动/被动模式,二进制传输 | 批量文件上传 |
1.3 Python网络编程
[!note] Python网络编程是指使用Python编写能够在不同计算设备之间通过网络进行通信的程序的过程。这种编程允许计算机软件利用网络基础设施,如互联网或局域网,实现数据交换、资源共享和分布式处理等功能。
一句话解释:“网络编程就是用代码让不同电脑/手机/设备互相通讯”
- 微信发消息 → 你的手机和腾讯服务器“聊天”
- 刷抖音 → 你的手机从抖音服务器“下载视频”
- 玩王者荣耀 → 你的手机和队友的手机“实时传数据”
为什么需要网络编程?
因为我们处于互联网时代!早已离不开网络,而相应的也产生的对应的需求:
- 数据共享:比如网盘同步文件
- 远程控制:比如远程办公操作公司电脑
- 实时交互:比如在线游戏、直播弹幕
- 服务集中化:比如微信服务器管理10亿用户的消息
2. 网络编程实践
2.1 HTTP协议:网络爬虫
[!note] 超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议,是万维网(WWW)的数据通信基础。它定义了浏览器(客户端)如何向服务器请求内容,以及服务器如何将内容返回给浏览器。
我们每天浏览网页使用的就是HTTP协议,编写Python代码也可以用来访问网页并抓取我们需要的内容,下面是一个简单的示例,用于访问豆瓣TOP250的页面。
使用requests
库发起GET请求获取网页内容:
python">import requests # 发起GET请求(伪装成浏览器)
headers = { "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36..."
}
response = requests.get("https://movie.douban.com/top250", headers=headers) # 检查状态码
if response.status_code == 200: print("成功获取数据!网页长度:", len(response.text))
else: print("请求失败,错误码:", response.status_code) # 提取数据
print(response.text[:500]) # 打印前500字符
小技巧:
- 使用
time.sleep(3)
避免高频请求被封IP - 通过
response.json()
直接解析JSON数据
2.2 TCP/UDP协议:打造你的“网络对讲机”
在Python中,我们可以使用socket
库来使用TCP/UDP协议进行通讯。
2.2.1 使用TCP协议进行可靠传输
[!note] 传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的传输层协议。它提供可靠的数据传输,确保数据的完整性和顺序。
TCP是面向连接的可靠传输协议,核心特点:
- 三次握手建立连接:确保双方通信准备就绪
- 数据完整性保障:自动重传丢失的数据包
- 有序传输:数据按发送顺序重组
- 流量控制:通过滑动窗口机制避免拥塞
借助TCP的特性,我们可以写一个接收数据的服务端和一个发送数据的客户端,实现数据传输!
服务端代码:
python">import socketdef tcp_server():# 创建TCP Socketserver = socket.socket(socket.AF_INET, socket.SOCK_STREAM)server.bind(('127.0.0.1', 8888)) # 绑定本机IP和端口server.listen(5) # 允许最多5个等待连接print("TCP服务端已启动,等待连接...")try:while True:client, addr = server.accept() # 接受客户端连接print(f"客户端 {addr} 已连接")# 接收数据(最多1024字节)data = client.recv(1024).decode('utf-8')print(f"收到消息:{data}")# 发送响应client.send(f"已收到:{data}".encode('utf-8'))client.close() # 关闭当前连接except KeyboardInterrupt:print("\n服务端关闭")server.close()if __name__ == '__main__':tcp_server()
客户端代码:
python">import socketdef tcp_client():client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)client.connect(('127.0.0.1', 8888)) # 连接服务端try:message = input("请输入要发送的消息:")client.send(message.encode('utf-8')) # 发送数据response = client.recv(1024).decode('utf-8')print(f"服务端响应:{response}")except ConnectionResetError:print("连接被服务端重置")finally:client.close()if __name__ == '__main__':tcp_client()
运行结果: 服务端可以正确的收到客户端发送的信息!
如果你有台具有公网IP的服务器,运行后是真的可以远程进行数据通讯,实现各种功能!
2.2.2 UDP协议:快如闪电
[!note] 用户数据报协议(UDP,User Datagram Protocol)是一种无连接的传输层协议。它不提供数据传输的可靠性保证,但比 TCP 协议更加快速和高效,适合在线会议、直播等需要即使收到数据的场景,但不能保证数据可靠,容易丢包,卡顿。
UDP是无连接的轻量级传输协议,核心特点:
- 无连接:直接发送数据,无需建立连接
- 高效快速:不保证数据顺序和可靠性
- 支持广播:可同时向多个目标发送数据
我们也可以使用UDP进行数据传输,实现更快的传输效果,但要注意,UDP传输是不可靠的,对方可能无法收到发送的消息!
服务端代码:
python">import socket# 创建UDP Socket
server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server.bind(('127.0.0.1', 8888)) # 绑定端口print("UDP服务端已启动...")
while True:data, addr = server.recvfrom(1024) # 接收数据print(f"收到来自 {addr} 的消息:{data.decode()}")
客户端代码:
python">import socketclient = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP Socketmessage = input("请输入消息:")
client.sendto(message.encode(), ('127.0.0.1', 8888)) # 直接发送
print("消息已发送")
client.close() # 非必须,但建议关闭
运行结果:
2.3 FTP协议:文件传输
使用ftplib
库就可以进行FTP协议进行文件传输,下面的代码仅作为样例,不能直接运行。
python">from ftplib import FTP # 连接FTP服务器
ftp = FTP('ftp.example.com')
ftp.login(user='username', passwd='password') # 上传文件
with open('local_file.txt', 'rb') as f: ftp.storbinary('STOR remote_file.txt', f) # 下载文件
with open('downloaded.txt', 'wb') as f: ftp.retrbinary('RETR remote_file.txt', f.write) # 列出目录
ftp.dir() ftp.quit()
避坑指南:
- 使用
FTP_TLS
实现加密传输 - 注意二进制模式(
'rb'
/'wb'
)防止文件损坏
2.4 WebSocket:双向通信
WebSocket核心特点:
- 全双工通信:客户端与服务端可同时发送数据
- 长连接:一次握手建立连接,持续通信(对比HTTP的短连接)
- 低延迟:头部开销小(仅2字节),适合高频交互场景
- 协议升级:基于HTTP握手,后续切换为
ws://
或wss://
协议
根据全双工的特性,我们可以写一个能够互相发送消息的案例,一个聊天软件的雏形就具备了!
服务端代码:
python">import asyncio
import websockets async def handle_client(websocket): # 接收消息任务 async def receive(): async for message in websocket: print(f"\n[客户端] {message}") # 发送消息任务(服务端主动输入) async def send(): while True: msg = await asyncio.get_event_loop().run_in_executor(None, input, "[服务端] 请输入消息:") await websocket.send(msg) # 并行运行收发任务 await asyncio.gather( receive(), send() )
async def main(): async with websockets.serve(handle_client, "localhost", 18765): print("服务端已启动,等待连接...") await asyncio.Future() asyncio.run(main())
客户端代码:
python">import asyncio
import websockets async def chat(): async with websockets.connect("ws://localhost:18765") as ws: # 接收消息任务 async def receive(): async for message in ws: print(f"\n[服务端] {message}") # 发送消息任务 async def send(): while True: msg = await asyncio.get_event_loop().run_in_executor(None, input, "[客户端] 请输入消息:") await ws.send(msg) # 双通道并行 await asyncio.gather( receive(), send() )
asyncio.run(chat())
运行结果:实现了双向通讯。
2.5 SMTP协议:自动收发邮件
[!note] 简单邮件传输协议(SMTP,Simple Mail Transfer Protocol)是一种用于发送电子邮件的协议。它定义了邮件服务器之间如何传递邮件,以及邮件客户端如何将邮件发送到邮件服务器,SMTP 协议默认使用 25 端口。
我们先来看看在现实生活中发送邮件的流程:
小明想给小红写情书💌 → 把信塞进邮筒 → 邮局分拣运输→ 送到小红家门口 → 小红收信
对应电子邮箱发送流程:
编写Python代码 → SMTP服务器 → 互联网传输 → 收件人邮件服务器 → 对方在邮箱客户端查看
拓展:
- SMTP协议:简单邮件传输协议,负责“邮局”之间的信件传递
- smtplib库:Python自带的SMTP协议工具包
- MIME协议:让邮件能携带附件/图片/HTML等丰富内容的“包装盒”
2.5.1 前置任务:配置你的邮箱
以QQ邮箱为例:
- 登录邮箱 → 设置 → 账户 → 开启POP3/SMTP服务
- 获取授权码(牢记,而且不要透露给其他人!有这个授权码就能使用你的邮箱)
2.5.2 发送纯文本邮件 ✉️
代码实现:
python">import smtplib
from email.mime.text import MIMEText # ----------- 配置邮箱信息 -----------
mail_host = "smtp.qq.com" # QQ邮箱SMTP服务器地址
mail_user = "your_email@qq.com" # 发件邮箱
mail_pass = "你的授权码" # 不是登录密码! # ----------- 信件内容 -----------
message = MIMEText("小红,今晚一起看《Python从入门到入土》吗?", "plain", "utf-8")
message["From"] = mail_user # 发件人
message["To"] = "xiaohong@163.com" # 收件人
message["Subject"] = "【重要】学习邀请函" # 主题 # ----------- 发送邮件 -----------
try: smtpObj = smtplib.SMTP_SSL(mail_host, 465) # 加密连接 smtpObj.login(mail_user, mail_pass) smtpObj.sendmail(mail_user, ["xiaohong@163.com"], message.as_string()) print("信件已成功送达!")
except Exception as e: print(f"发送失败: {e}")
finally: smtpObj.quit()
注意:
- 端口号用465(SSL加密)或587(TLS加密)
- 收件人列表可以是多个邮箱,如
["a@qq.com", "b@163.com"]
- 若遇
SMTPAuthenticationError
,99%是授权码错误
运行代码后,小红就收到邮件了:
3. 小结
要点总结:
协议/技术 | 核心功能 | Python模块 | 典型应用场景 |
---|---|---|---|
TCP | 可靠传输、有序交付 | socket | 文件传输、Web通信 |
UDP | 快速传输、支持广播 | socket | 实时视频、DNS查询 |
HTTP/HTTPS | 客户端-服务端请求响应 | requests | 网页爬虫、API交互 |
WebSocket | 全双工实时通信 | websockets | 在线聊天、股票行情推送 |
SMTP | 邮件发送(支持SSL加密) | smtplib +email | 系统告警、营销邮件 |
FTP | 文件传输(主动/被动模式) | ftplib | 批量文件上传/下载 |
🚀 立即动手实践
- 运行TCP/UDP示例:体验可靠传输 vs 极速传输的差异
- 部署WebSocket聊天室:感受全双工通信的实时性
- 配置SMTP发件功能:用代码给你的好友发送一封自动邮件