1. 网络编程基础:从单机到互联
作为一名Python开发者,你可能已经习惯了编写单机运行的程序。但真正的编程乐趣往往来自于让不同计算机之间的程序能够相互"交流"。想象一下,如果没有网络编程,我们就没有网页浏览、在线游戏、即时通讯这些改变世界的应用。
网络编程的核心在于理解计算机之间如何建立连接并进行数据交换。这就像是在不同城市的朋友之间建立电话系统 - 需要统一的号码规则(IP地址)、呼叫方式(协议)和通话线路(Socket)。
1.1 网络通信的基本要素
任何网络通信都需要三个基本要素:
-
标识符(IP地址):就像每部电话需要唯一的号码,网络中的每台计算机都需要一个IP地址。IPv4地址由四个0-255的数字组成,如192.168.1.1。
-
服务入口(端口):一台计算机可能同时运行多个网络服务,端口号(0-65535)帮助区分这些服务。常见服务有固定端口,如HTTP(80)、SSH(22)。
-
通信规则(协议):TCP和UDP是最常用的两种传输层协议,决定了数据传输的可靠性和方式。
提示:开发时建议使用1024以上的端口,避免与系统服务冲突。我常用8888、9999这类易记的端口号进行测试。
1.2 TCP vs UDP:两种通信方式的本质区别
理解TCP和UDP的区别对网络编程至关重要:
TCP(传输控制协议)特点:
- 面向连接:通信前需建立稳定连接(三次握手)
- 可靠传输:确保数据顺序和完整性
- 流量控制:避免发送方淹没接收方
- 典型应用:网页浏览(HTTP)、文件传输(FTP)、电子邮件
UDP(用户数据报协议)特点:
- 无连接:直接发送数据包,不建立连接
- 尽最大努力交付:不保证数据到达或顺序
- 开销小、延迟低
- 典型应用:视频会议、在线游戏、DNS查询
选择建议:需要可靠传输选TCP,追求实时性选UDP。我曾在视频直播项目中使用UDP,虽然会有少量丢包,但延迟比TCP低很多,用户体验更好。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Socket编程核心:TCP通信实现
2.1 Socket通信的基本流程
Socket是操作系统提供的网络通信接口,TCP通信流程可以类比打电话:
-
服务器端:
- 创建Socket(买电话)
- 绑定IP和端口(安装电话线并分配号码)
- 监听连接(等待来电)
- 接受连接(接听电话)
- 收发数据(通话)
- 关闭连接(挂断)
-
客户端:
- 创建Socket(买电话)
- 连接服务器(拨号)
- 收发数据(通话)
- 关闭连接(挂断)
2.2 完整TCP服务器实现
下面是一个增强版的TCP服务器代码,增加了错误处理和日志记录:
python复制import socket
import logging
# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
def run_tcp_server(host='0.0.0.0', port=8888):
"""
TCP服务器实现
:param host: 监听地址,0.0.0.0表示所有可用接口
:param port: 监听端口
"""
try:
# 创建TCP Socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 设置端口复用,避免Address already in use错误
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 绑定地址和端口
server_socket.bind((host, port))
logger.info(f"服务器启动,监听 {host}:{port}")
# 开始监听,设置最大等待连接数为5
server_socket.listen(5)
while True:
try:
# 等待客户端连接
client_sock, addr = server_socket.accept()
logger.info(f"客户端 {addr} 已连接")
# 设置接收超时(5秒)
client_sock.settimeout(5.0)
# 处理客户端请求
while True:
try:
# 接收数据(最大1024字节)
data = client_sock.recv(1024)
if not data:
logger.info(f"客户端 {addr} 主动断开连接")
break
# 解码并处理数据
msg = data.decode('utf-8')
logger.info(f"收到来自 {addr} 的消息: {msg}")
# 构造响应
response = f"已收到你的消息: {msg}"
client_sock.send(response.encode('utf-8'))
except socket.timeout:
logger.warning(f"与 {addr} 的通信超时")
break
except Exception as e:
logger.error(f"处理客户端 {addr} 请求时出错: {str(e)}")
break
except Exception as e:
logger.error(f"处理客户端连接时出错: {str(e)}")
finally:
# 确保客户端Socket关闭
if 'client_sock' in locals():
client_sock.close()
except Exception as e:
logger.error(f"服务器运行出错: {str(e)}")
finally:
# 确保服务器Socket关闭
if 'server_socket' in locals():
server_socket.close()
logger.info("服务器已关闭")
if __name__ == '__main__':
run_tcp_server()
这个版本增加了以下改进:
- 完善的日志记录,方便调试和问题追踪
- 超时处理,避免客户端无响应导致服务器阻塞
- 异常处理,增强程序健壮性
- 资源清理,确保Socket正确关闭
2.3 TCP客户端实现与交互
配套的TCP客户端可以这样实现:
python复制import socket
import sys
def run_tcp_client(server_ip='127.0.0.1', server_port=8888):
"""
TCP客户端实现
:param server_ip: 服务器IP地址
:param server_port: 服务器端口
"""
try:
# 创建TCP Socket
