网络编程就是让两台或多台电脑通过网络互相发送、接收数据。Python 内置了socket模块可以非常方便地实现网络通信是爬虫、后端服务、聊天程序、远程控制等功能的底层基础。本文从最基础的网络概念讲起全程用通俗类比 可运行代码示例零基础也能一步步跑通、理解。一、前置必懂核心基础概念先把几个最核心的概念搞明白不然代码你只能抄不知道为什么这么写。1. 生活类比网络通信 打电话我们把两台电脑的通信类比成两个人打电话IP 地址相当于对方的「电话号码」用来定位到具体哪一台电脑端口号相当于「分机号」一台电脑上有很多程序端口号用来区分数据发给哪个程序Socket套接字相当于「电话机」是通信的工具所有数据收发都通过 socket 完成协议相当于「通话规则」比如要说普通话、先问好再说话保证双方能听懂对方2. IP 地址和端口号IP 地址定位电脑格式比如192.168.1.100本机测试用固定回环地址127.0.0.1不需要联网也能测试端口号定位程序范围 0~655350~1023系统保留端口比如网页服务默认 80 端口、SSH 默认 22 端口我们自己写程序用 1024~65535 之间的端口即可同一台电脑上一个端口只能被一个程序占用3. 两大核心协议TCP 和 UDP这是网络编程最常用的两种通信方式区别非常重要表格对比项TCP 协议UDP 协议连接方式面向连接必须先建立连接才能通信像打电话先拨号接通再说话无连接不需要建立连接直接发数据像发短信直接发过去可靠性可靠保证数据不丢、不乱序、不重复不可靠不保证数据一定送到可能丢包传输速度稍慢更快适用场景文件传输、网页、聊天、登录支付等需要可靠数据的场景视频直播、语音通话、游戏同步等追求速度、允许少量丢包的场景4. Socket 是什么Socket 是操作系统提供的「网络通信工具」Python 的socket模块就是对操作系统底层 socket 的封装。 不管是 TCP 还是 UDP 通信都是通过创建 socket 对象调用它的方法来收发数据。二、TCP 网络编程重点最常用TCP 是「面向连接」的可靠协议通信分为服务端和客户端服务端被动等待连接一直开着等客户端连上来客户端主动发起连接连不上就报错1. TCP 通信的完整流程服务端流程接电话的人创建 socket 电话机绑定 IP 地址和端口号绑定电话号码 分机号开启监听等待连接待机等别人打过来接收客户端连接建立通信通道接听电话收发数据通话关闭连接挂电话客户端流程打电话的人创建 socket 电话机连接服务端的 IP 端口拨号收发数据通话关闭连接挂电话2. 最简 TCP 服务端代码逐行讲解新建一个文件tcp_server.py复制下面的代码# 1. 导入内置socket模块不用安装 import socket # 2. 创建TCP socket对象 # AF_INET 表示用IPv4地址SOCK_STREAM 表示用TCP协议 server_socket socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 3. 绑定IP和端口 # 参数是元组(IP地址, 端口号) # 127.0.0.1 表示只能本机访问0.0.0.0 表示允许所有电脑访问 server_socket.bind((127.0.0.1, 8888)) # 4. 开启监听 # 参数5表示最多同时等待5个连接请求新手不用深究写个数字就行 server_socket.listen(5) print(服务端已启动在8888端口等待客户端连接...) # 5. 等待客户端连接阻塞等待没人连就一直停在这里等 # accept() 会返回两个值新的socket对象、客户端的地址(IP,端口) client_socket, client_addr server_socket.accept() print(f有客户端连接上来了地址{client_addr}) # 6. 接收客户端发来的数据 # recv(1024) 表示一次最多接收1024字节数据返回的是bytes字节类型 recv_data client_socket.recv(1024) # 字节转字符串decode() 解码默认用utf-8 recv_text recv_data.decode(utf-8) print(f收到客户端消息{recv_text}) # 7. 给客户端回消息 # 字符串转字节encode() 编码 send_text 你好我是服务端收到你的消息了 client_socket.send(send_text.encode(utf-8)) # 8. 关闭连接 client_socket.close() # 关闭和这个客户端的连接 server_socket.close() # 关闭服务端socket print(服务端关闭) 新手必懂accept()和recv()默认是「阻塞」的 —— 没有连接 / 没有数据时程序会停在这里等不会往下走。3. 最简 TCP 客户端代码逐行讲解新建另一个文件tcp_client.py和服务端放在同一个文件夹import socket # 1. 创建TCP socket对象 client_socket socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 2. 连接服务端参数是(服务端IP, 服务端端口) # 因为是本机测试IP写127.0.0.1端口和服务端一致8888 client_socket.connect((127.0.0.1, 8888)) print(成功连接到服务端) # 3. 给服务端发消息 msg 你好服务端我是客户端 client_socket.send(msg.encode(utf-8)) # 4. 接收服务端的回复 recv_data client_socket.recv(1024) print(f收到服务端回复{recv_data.decode(utf-8)}) # 5. 关闭连接 client_socket.close() print(客户端关闭)4. 运行测试新手必看步骤先运行服务端打开命令行执行python tcp_server.py此时会看到服务端已启动在8888端口等待客户端连接...程序会停住等待客户端连接这是正常的阻塞状态再运行客户端再开一个新的命令行窗口执行python tcp_client.py客户端窗口会显示连接成功、收到服务端回复服务端窗口会显示有客户端连接、收到客户端消息运行完两个程序都会自动关闭。⚠️ 新手高频坑先运行客户端、后运行服务端会直接报错ConnectionRefusedError因为服务端没开连接不上。必须先开服务端再开客户端。5. 进阶持续聊天的 TCP 服务端上面的例子只能发一次消息就关闭了我们可以加循环实现「你一句我一句」的持续通信。升级版服务端tcp_server_loop.pyimport socket server_socket socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind((127.0.0.1, 8888)) server_socket.listen(5) print(服务端启动等待连接...) client_socket, client_addr server_socket.accept() print(f客户端{client_addr}已连接) while True: # 接收消息 recv_data client_socket.recv(1024) recv_text recv_data.decode(utf-8) print(f客户端说{recv_text}) # 客户端发exit就退出循环 if recv_text exit: print(客户端退出结束通信) break # 回复消息 reply f收到{recv_text} client_socket.send(reply.encode(utf-8)) client_socket.close() server_socket.close()升级版客户端tcp_client_loop.pyimport socket client_socket socket.socket(socket.AF_INET, socket.SOCK_STREAM) client_socket.connect((127.0.0.1, 8888)) print(连接服务端成功输入exit退出) while True: # 用户输入消息 msg input(请输入要发送的内容) client_socket.send(msg.encode(utf-8)) if msg exit: print(退出聊天) break # 接收回复 recv_data client_socket.recv(1024) print(f服务端回复{recv_data.decode(utf-8)}) client_socket.close()运行后可以在客户端反复输入内容服务端自动回复输入exit就结束。 说明这个版本一次只能服务一个客户端想同时服务多个客户端需要配合多线程新手先把单客户端的基础吃透。三、UDP 网络编程UDP 是「无连接」的协议不需要提前建立连接知道对方的 IP 端口就能直接发数据速度快但不保证可靠。1. UDP 的特点没有服务端、客户端的严格区分两边地位平等不需要listen()、connect()、accept()创建完 socket 直接收发发送用sendto()需要指定对方地址接收用recvfrom()会返回数据和对方地址2. UDP 接收端类似服务端新建udp_receiver.pyimport socket # 创建UDP socketSOCK_DGRAM 表示UDP协议 udp_socket socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 绑定端口等待别人发数据到这个端口 udp_socket.bind((127.0.0.1, 9999)) print(UDP接收端已启动等待数据...) while True: # 接收数据返回(数据字节, 发送方地址) recv_data, sender_addr udp_socket.recvfrom(1024) recv_text recv_data.decode(utf-8) print(f收到来自{sender_addr}的消息{recv_text}) # 收到exit就退出 if recv_text exit: print(结束接收) break # 回复对方 reply f已收到{recv_text} udp_socket.sendto(reply.encode(utf-8), sender_addr) udp_socket.close()3. UDP 发送端类似客户端新建udp_sender.pyimport socket # 创建UDP socket udp_socket socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 目标地址接收端的IP和端口 target_addr (127.0.0.1, 9999) while True: msg input(请输入要发送的内容) # 直接发送数据指定目标地址不需要提前连接 udp_socket.sendto(msg.encode(utf-8), target_addr) if msg exit: print(退出发送) break # 接收回复 recv_data, _ udp_socket.recvfrom(1024) print(f对方回复{recv_data.decode(utf-8)}) udp_socket.close()运行测试先运行接收端python udp_receiver.py再运行发送端python udp_sender.py发送端输入内容接收端就能收到输入exit退出。对比 TCPUDP 不需要建立连接写法更简单但是数据可能丢包适合对可靠性要求不高、追求速度的场景。四、新手高频易错点 避坑指南1. 编码错误字符串和字节搞混网络传输的只能是字节bytes不能直接传字符串。发数据字符串 → 字节用.encode(utf-8)收数据字节 → 字符串用.decode(utf-8)错误示范直接发字符串# ❌ 报错a bytes-like object is required, not str client_socket.send(你好)正确写法# ✅ 先编码成字节 client_socket.send(你好.encode(utf-8))2. 连接失败ConnectionRefusedError原因基本都是三个服务端没启动先开服务端再开客户端端口号写错了客户端和服务端端口必须一致IP 地址写错了本机测试用127.0.0.13. 端口被占用Address already in use如果程序异常退出端口可能还被占用着再启动就会报错。解决 1换一个端口号比如从 8888 改成 8889解决 2杀掉占用端口的进程新手直接换端口更简单4. recv () 一直卡住收不到数据recv()是阻塞的对方没发数据就会一直等。如果觉得卡住了先检查对方有没有成功发送数据、编码是否正确。5. 防火墙拦截如果两台不同的电脑通信失败先检查防火墙是否拦截了对应的端口本机测试不会有这个问题。五、核心总结网络编程本质两台电脑通过 socket 收发字节数据IP 定位电脑端口定位程序TCP 编程步骤服务端创建 socket → 绑定 bind → 监听 listen → 接收连接 accept → 收发 recv/send → 关闭客户端创建 socket → 连接 connect → 收发 recv/send → 关闭UDP 编程步骤创建 socket → 直接收发 sendto/recvfrom → 关闭选型建议需要可靠传输选 TCP追求速度、允许丢包选 UDP必记规则网络传输用字节字符串收发必须编解码