Python网络编程

一、网络编程基础铺垫

Python网络编程基于OSI七层模型/TCP/IP四层模型,核心是通过"套接字(socket)"实现不同设备间的通信,socket是网络通信的端点,负责建立连接、发送/接收数据。

核心前提:网络通信的本质是"数据的传输",TCP和UDP是传输层(TCP/IP四层模型)的两种核心协议,决定了数据传输的方式和特性,Python中通过socket模块直接调用这两种协议。

二、TCP协议(Transmission Control Protocol)

2.1 核心概念

TCP(传输控制协议),是一种面向连接、可靠、面向字节流的传输层协议。核心特点是"可靠传输",通过一系列机制确保数据准确、完整、有序地从发送方传递到接收方,适用于对数据可靠性要求高的场景。

核心机制(简要了解,贴合运维学习):

  • 三次握手:建立连接(客户端→服务器、服务器→客户端、客户端→服务器),确保双方通信通道通畅。

  • 四次挥手:关闭连接,确保双方都已完成数据传输,避免数据丢失。

  • 重传机制:若数据丢失或出错,自动重传,直至接收方确认收到。

  • 流量控制/拥塞控制:避免发送方发送过快,导致接收方无法处理,或网络拥塞。

2.2 Python中TCP编程核心

使用socket模块,创建TCP套接字(SOCK_STREAM),分为服务器端和客户端:

  1. 服务器端流程:创建socket→绑定IP和端口(bind)→监听连接(listen)→接受连接(accept)→收发数据(recv/send)→关闭连接(close)。

  2. 客户端流程:创建socket→连接服务器(connect)→收发数据(send/recv)→关闭连接(close)。

关键注意:TCP是面向连接的,必须先建立连接(三次握手),才能传输数据;数据传输是"字节流",无固定边界,需自定义分隔符或约定数据长度。

2.3 应用场景

适用于数据可靠性优先,对延迟要求不极致的场景,运维工作中高频接触:

  • HTTP/HTTPS协议:网页浏览、接口调用(如运维脚本调用接口获取服务器状态)。

  • 文件传输:FTP、SCP(运维中传输配置文件、日志文件)。

  • 远程控制:SSH(运维核心,远程登录服务器执行命令)、Telnet(老式远程控制)。

  • 数据库连接:MySQL、PostgreSQL等数据库的客户端与服务器通信(运维中操作数据库)。

  • 邮件传输(SMTP、POP3):确保邮件不丢失、不错乱。

三、UDP协议(User Datagram Protocol)

3.1 核心概念

UDP(用户数据报协议),是一种无连接、不可靠、面向数据报的传输层协议。核心特点是"快速传输",不建立连接、不保证数据可靠送达,仅负责将数据报发送出去,适用于对延迟敏感、可接受少量数据丢失的场景。

核心特性(与TCP对比):

  • 无连接:无需三次握手/四次挥手,直接发送数据,启动速度快。

  • 不可靠:不确认数据是否收到、不重传丢失数据、不保证数据顺序,可能出现丢包、乱序。

  • 面向数据报:数据以"数据报"为单位传输,每个数据报有固定边界,接收方一次接收一个完整数据报。

  • 开销小:无需维护连接状态,协议开销远小于TCP,传输效率高。

3.2 Python中UDP编程核心

使用socket模块,创建UDP套接字(SOCK_DGRAM),分为服务器端和客户端:

  1. 服务器端流程:创建socket→绑定IP和端口(bind)→接收/发送数据(recvfrom/sendto)→关闭连接(close)。

  2. 客户端流程:创建socket→直接发送/接收数据(sendto/recvfrom)→关闭连接(close)。

关键注意:UDP无连接,客户端无需先连接服务器,可直接发送数据;recvfrom会获取发送方的IP和端口,便于回复。

3.3 应用场景

适用于延迟优先、可接受少量丢包的场景,运维中也有相关应用:

  • 网络监控:ping命令(基于ICMP,底层依赖UDP思想)、SNMP协议(运维中监控网络设备、服务器状态,快速采集数据)。

  • 实时通信:视频通话、语音通话(如Zoom、微信语音,允许少量丢包,优先保证流畅)、实时直播。

  • 广播/组播:局域网内设备通知(如运维中批量发送设备唤醒指令)、DNS查询(域名解析,快速获取IP,可接受重试)。

  • 游戏通信:网络游戏(如射击类游戏,优先保证实时性,少量丢包不影响整体体验)。

四、TCP与UDP核心对比(重点,便于记忆)

对比维度 TCP UDP
连接方式 面向连接(三次握手建立,四次挥手关闭) 无连接(直接发送,无需建立连接)
可靠性 可靠(重传、确认、有序) 不可靠(无确认、无重传,可能丢包、乱序)
数据传输方式 面向字节流(无固定边界,需自定义分隔) 面向数据报(有固定边界,一次接收一个数据报)
开销 大(需维护连接状态、重传等机制) 小(无连接,协议简单)
延迟 高(建立连接、重传等耗时) 低(直接发送,无额外耗时)
运维常见应用 SSH、FTP、数据库连接、接口调用 ping、SNMP监控、DNS查询、局域网广播

五、Python网络编程关键注意点(运维视角)

  • 端口使用:1-1024为系统端口,建议使用1024以上端口避免冲突(运维中需注意端口占用问题)。

  • 异常处理:网络编程中需捕获连接超时、连接中断等异常(如try-except语句),避免脚本崩溃。

  • 编码问题:发送数据时需将字符串转为字节流(encode()),接收时转为字符串(decode()),避免乱码。

  • 运维场景:Python网络编程常用于编写监控脚本(如UDP实现设备心跳检测)、自动化部署脚本(如TCP连接服务器传输文件)。

六、实验过程(TCP与UDP实操,运维视角)

6.1 实验环境准备

  1. 环境要求:Python 3.6+(自带socket模块,无需额外安装),Linux系统(推荐CentOS/Ubuntu,贴合运维实际工作环境)。

  2. 工具:终端(2个,分别运行服务器端和客户端脚本)、文本编辑器(编写Python脚本)。

  3. 前提:关闭防火墙(避免端口被拦截),执行命令:

CentOS:systemctl stop firewalld;Ubuntu:ufw disable

  1. 测试IP:本地回环地址127.0.0.1(无需联网,便于快速测试),端口选用10086(1024以上,避免冲突)。

6.2 实验1:TCP客户端与服务器通信(可靠传输)

6.2.1 编写服务器端脚本(tcp_server.py)

脚本功能:监听指定IP和端口,接受客户端连接,接收客户端发送的数据,回复确认信息,模拟运维中服务器接收客户端指令的场景。

bash 复制代码
import socket
​
# 1. 创建TCP套接字
tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2. 绑定IP和端口(元组格式:(IP, 端口))
tcp_server.bind(("127.0.0.1", 10086))
# 3. 监听连接(参数为最大等待连接数,运维中常用5)
tcp_server.listen(5)
print("TCP服务器已启动,监听127.0.0.1:10086,等待客户端连接...")
​
# 4. 接受客户端连接(阻塞式,直到有客户端连接)
client_conn, client_addr = tcp_server.accept()
print(f"已连接客户端:{client_addr}")
​
# 5. 收发数据(循环接收,直到客户端发送"exit")
while True:
    # 接收数据(1024表示每次接收的最大字节数,运维中常用1024/4096)
    recv_data = client_conn.recv(1024)
    # 解码字节流为字符串
    recv_str = recv_data.decode("utf-8")
    print(f"收到客户端消息:{recv_str}")
    
    # 若客户端发送"exit",关闭连接
    if recv_str == "exit":
        client_conn.send("已收到退出指令,连接关闭".encode("utf-8"))
        break
    # 回复客户端,模拟运维中服务器响应指令
    client_conn.send(f"服务器已收到消息:{recv_str}".encode("utf-8"))
​
# 6. 关闭连接(先关客户端连接,再关服务器)
client_conn.close()
tcp_server.close()
print("TCP服务器已关闭")

6.2.2 编写客户端脚本(tcp_client.py)

脚本功能:连接TCP服务器,发送数据(模拟运维中客户端向服务器发送指令),接收服务器回复。

bash 复制代码
import socket
​
# 1. 创建TCP套接字
tcp_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2. 连接服务器(指定服务器IP和端口)
tcp_client.connect(("127.0.0.1", 10086))
print("已连接TCP服务器,可发送消息(输入exit退出)...")
​
# 3. 收发数据(循环发送,直到输入exit)
while True:
    send_str = input("请输入要发送的消息:")
    # 编码字符串为字节流,发送数据
    tcp_client.send(send_str.encode("utf-8"))
    # 接收服务器回复
    recv_data = tcp_client.recv(1024)
    print(f"服务器回复:{recv_data.decode('utf-8')}")
    # 若输入exit,退出循环,关闭连接
    if send_str == "exit":
        break
​
# 4. 关闭客户端连接
tcp_client.close()
print("TCP客户端已关闭")

6.2.3 执行实验步骤

  1. 打开第一个终端,进入脚本所在目录,执行服务器端脚本:python3 tcp_server.py,此时终端显示"TCP服务器已启动,监听127.0.0.1:10086,等待客户端连接..."。

  2. 打开第二个终端,进入同一目录,执行客户端脚本:python3 tcp_client.py,此时客户端显示"已连接TCP服务器,可发送消息(输入exit退出)...",服务器端显示"已连接客户端:('127.0.0.1', 端口号)"(端口号随机)。

  3. 在客户端输入任意消息(如"查看服务器CPU使用率"),按下回车,客户端会显示服务器回复,服务器端会显示收到的客户端消息。

  4. 在客户端输入"exit",按下回车,客户端和服务器端会依次关闭连接,实验结束。

实验现象:数据传输稳定,无丢包、乱序,客户端发送的所有消息都能被服务器接收并回复,体现TCP的可靠传输特性。

6.3 实验2:UDP客户端与服务器通信(快速传输)

6.3.1 编写服务器端脚本(udp_server.py)

脚本功能:绑定IP和端口,接收客户端发送的数据报,回复确认信息,模拟运维中SNMP监控数据采集的场景(快速接收终端数据)。

bash 复制代码
import socket
​
# 1. 创建UDP套接字
udp_server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 2. 绑定IP和端口
udp_server.bind(("127.0.0.1", 10086))
print("UDP服务器已启动,绑定127.0.0.1:10086,等待接收数据...")
​
# 3. 接收并回复数据(循环接收,直到收到"exit")
while True:
    # recvfrom返回两个值:接收的数据、发送方的IP和端口
    recv_data, client_addr = udp_server.recvfrom(1024)
    recv_str = recv_data.decode("utf-8")
    print(f"收到来自{client_addr}的消息:{recv_str}")
    
    # 若收到"exit",停止接收
    if recv_str == "exit":
        udp_server.sendto("已收到退出指令,停止接收".encode("utf-8"), client_addr)
        break
    # 回复客户端
    send_str = f"服务器已接收消息:{recv_str}"
    udp_server.sendto(send_str.encode("utf-8"), client_addr)
​
# 4. 关闭UDP服务器
udp_server.close()
print("UDP服务器已关闭")

6.3.2 编写客户端脚本(udp_client.py)

脚本功能:向UDP服务器发送数据报,接收服务器回复,模拟运维中终端向监控服务器发送心跳数据的场景。

bash 复制代码
import socket
​
# 1. 创建UDP套接字
udp_client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 服务器IP和端口(无需提前连接)
server_addr = ("127.0.0.1", 10086)
print("UDP客户端已启动,可发送消息(输入exit退出)...")
​
# 2. 发送并接收数据(循环发送)
while True:
    send_str = input("请输入要发送的消息:")
    # 发送数据报(指定服务器地址)
    udp_client.sendto(send_str.encode("utf-8"), server_addr)
    # 接收服务器回复
    recv_data, server_addr = udp_client.recvfrom(1024)
    print(f"服务器回复:{recv_data.decode('utf-8')}")
    # 输入exit,退出循环
    if send_str == "exit":
        break
​
# 3. 关闭UDP客户端
udp_client.close()
print("UDP客户端已关闭")

6.4 实验总结(运维重点)

  • TCP实验:模拟运维中"客户端-服务器"可靠通信场景(如文件传输、指令下发),核心是确保数据不丢失、不混乱。

  • UDP实验:模拟运维中"终端-监控服务器"快速通信场景(如心跳检测、数据采集),核心是优先保证传输速度,可接受少量丢包。

  • 实操注意:运维中编写脚本时,需根据场景选择协议;端口需避开系统端口,避免冲突;需添加异常处理(如连接超时、端口占用),避免脚本崩溃。

相关推荐
闻道且行之1 小时前
虚拟机三种网络模式全解析(桥接 / NAT / 仅主机)
网络·智能路由器·vmware·虚拟机
万粉变现经纪人2 小时前
如何解决 pip install ta-lib 报错 本地 TA-Lib 库未安装 问题
数据库·python·scrapy·oracle·bug·pandas·pip
乔克19982 小时前
代理连接失败的问题
python·httpx
猫咪老师2 小时前
Day11 Python 关于线程和进程的最详细介绍!
后端·python
|华|2 小时前
Python操作MySQL数据库
数据库·python·mysql
wanhengidc2 小时前
云手机对小说工作室的作用
运维·服务器·网络·网络协议·智能手机
alphaTao2 小时前
LeetCode 每日一题 2026/4/6-2026/4/12
python·算法·leetcode
zzwq.2 小时前
PyMySQL 详解:从入门到实战,Python 操作 MySQL 一站式指南
开发语言·python
盟接之桥2 小时前
盟接之桥®说制造:从“制造”到“智造”,以品类品牌重塑制造业的生态未来
大数据·网络·人工智能·学习·制造