2026/4/18 7:28:59
网站建设
项目流程
番禺人才市场档案中心,网站排名优化要多少钱,彩票网站链接怎么做,WordPress中文king主题Day 26#xff1a;【99天精通Python】网络编程入门 (Socket) - 让电脑互相打电话
前言
欢迎来到第26天#xff01;
在此之前#xff0c;我们的程序都只是在自己的电脑上自言自语#xff08;单机版#xff09;。但互联网的魅力在于互联互通。通过网络编程…Day 26【99天精通Python】网络编程入门 (Socket) - 让电脑互相打电话前言欢迎来到第26天在此之前我们的程序都只是在自己的电脑上自言自语单机版。但互联网的魅力在于互联互通。通过网络编程我们可以让运行在不同电脑甚至不同国家上的程序进行数据交换。比如浏览网页浏览器 - 服务器、玩在线游戏客户端 - 游戏服务器、聊天软件你 - 腾讯服务器 - 朋友。今天我们将学习网络编程的基石——Socket套接字并亲手编写一个聊天程序让两台程序能够隔空对话。本节内容网络基础IP、端口、TCP/UDPSocket 通信流程TCP 服务器与客户端开发UDP 编程简介实战练习简易聊天室一、网络基础三板斧在写代码前必须搞懂三个概念1.1 IP 地址 (住址)用来唯一标识网络中的一台计算机。本地回环地址127.0.0.1(localhost)代表我自己。局域网地址如192.168.1.5。公网地址百度服务器的 IP。1.2 端口 (门牌号)一台电脑上运行着很多程序数据发过来该给谁靠端口区分。范围0-65535。知名端口HTTP(80), HTTPS(443), SSH(22)。我们在写程序时通常使用 1024 以上的端口如 8888, 9999避免冲突。1.3 协议 (语言)TCP (传输控制协议)打电话。可靠连接后才能通信保证数据不丢、不乱。适合传文件、网页、邮件。UDP (用户数据报协议)寄信/广播。不可靠发出去就不管了可能丢包但速度快。适合视频直播、语音通话。二、Socket 通信流程 (TCP版)Socket 是操作系统提供的网络编程接口。TCP 通信就像打电话流程非常固定客户端 (Client)服务器 (Server)客户端 (Client)服务器 (Server)loop[数据传输]socket() 创建bind() 绑定IP端口listen() 监听socket() 创建connect() 拨号/连接accept() 接听send() 说话recv() 听见send() 回复recv() 听见close() 挂断close() 挂断三、实战编写 TCP 服务器与客户端我们将编写一个 “Echo Server”回声服务器客户端发什么服务器就回复什么。3.1 TCP 服务器 (Server.py)importsocket# 1. 创建 Socket 对象# AF_INET: IPv4# SOCK_STREAM: TCP 协议server_socketsocket.socket(socket.AF_INET,socket.SOCK_STREAM)# 2. 绑定 IP 和 端口# 0.0.0.0 表示允许任何 IP 连接我# 8888 是端口号server_socket.bind((0.0.0.0,8888))# 3. 开始监听 (最大等待连接数 5)server_socket.listen(5)print(服务器启动等待连接...)# 4. 等待客户端连接 (阻塞直到有连接进来)# client_sock: 用于和这个特定客户端通信的socket# addr: 客户端的 (IP, Port)client_sock,addrserver_socket.accept()print(f客户端{addr}已连接)# 5. 接收与发送数据whileTrue:# recv(1024): 一次最多接收 1024 字节dataclient_sock.recv(1024)ifnotdata:# 客户端断开连接print(客户端已断开。)breakmsgdata.decode(utf-8)# 解码print(f收到消息:{msg})# 回复消息 (编码为 bytes)responsef服务端收到:{msg}client_sock.send(response.encode(utf-8))# 6. 关闭连接client_sock.close()server_socket.close()3.2 TCP 客户端 (Client.py)importsocket# 1. 创建 Socketclient_socketsocket.socket(socket.AF_INET,socket.SOCK_STREAM)# 2. 连接服务器 (IP, Port)# 如果服务器在另一台电脑这里填那台电脑的 IPclient_socket.connect((127.0.0.1,8888))whileTrue:msginput(请输入发送内容 (q退出): )ifmsgq:break# 3. 发送数据client_socket.send(msg.encode(utf-8))# 4. 接收回复recv_dataclient_socket.recv(1024)print(recv_data.decode(utf-8))# 5. 关闭client_socket.close()运行方式先运行Server.py看到服务器启动。再运行Client.py。在客户端输入文字观察服务器的反应。四、UDP 编程简介UDP 不需要建立连接没有listen和accept上来直接发简单粗暴。4.1 UDP 服务器importsocket# SOCK_DGRAM 代表 UDPudp_serversocket.socket(socket.AF_INET,socket.SOCK_DGRAM)udp_server.bind((0.0.0.0,9999))print(UDP 服务器启动...)whileTrue:# recvfrom 返回 (数据, (ip, port))data,addrudp_server.recvfrom(1024)print(f来自{addr}的消息:{data.decode()})4.2 UDP 客户端importsocket udp_clientsocket.socket(socket.AF_INET,socket.SOCK_DGRAM)# 不需要 connect直接 sendtoudp_client.sendto(Hello UDP.encode(),(127.0.0.1,9999))udp_client.close()五、实战练习简易多人聊天室 (Socket Threading)上面的 TCP 服务器有一个大问题accept后进入while循环处理消息这期间如果有第二个客户端连接会被阻塞住排队等待。为了支持多人聊天我们需要结合Day 24 (多线程)的知识主线程负责监听连接每来一个用户就开启一个新线程专门服务他。importsocketimportthreadingdefhandle_client(client_sock,addr):处理单个客户端的线程函数print(f用户{addr}加入聊天。)try:whileTrue:dataclient_sock.recv(1024)ifnotdata:breakmsgdata.decode(utf-8)print(f[{addr[0]}:{addr[1]}] 说:{msg})# 简单的回显实际聊天室应该把消息转发给所有其他 socketclient_sock.send(f服务器已阅:{msg}.encode(utf-8))exceptExceptionase:print(f连接异常:{e})finally:print(f用户{addr}退出。)client_sock.close()defmain():serversocket.socket(socket.AF_INET,socket.SOCK_STREAM)server.bind((0.0.0.0,8888))server.listen(10)# 允许10人排队print(多人聊天服务器启动...)whileTrue:# 主线程只负责接待client,addrserver.accept()# 创建分身线程去专门服务这个用户tthreading.Thread(targethandle_client,args(client,addr))t.start()if__name____main__:main()六、常见问题Q1为什么接收/发送都要 encode/decode网络传输的底层是字节流 (bytes)不是字符串 (string)。发送前字符串 - bytes (encode)接收后bytes - 字符串 (decode)Q2端口被占用 (Address already in use) 怎么办程序非正常退出时端口可能没释放。等一分钟再试操作系统会自动回收。代码中添加setsockopt允许端口复用在 bind 之前server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)Q3TCP 粘包问题TCP 是流式协议你发了 “A” 和 “B”接收端可能一次性收到 “AB”。解决办法设计应用层协议比如每条消息前加上长度头先发4个字节表示消息长度再发消息体。七、小结网络编程 SocketTCP (可靠)UDP (快速)Server: bind - listen - acceptClient: connectsend / recv无连接sendto / recvfrom并发处理Socket Threading主线程 accept子线程 recv关键要点TCP是打电话连接、可靠UDP是广播无连接、不可靠。Socket是通信的端点由 IP 和端口组成。写服务器时记住“bind - listen - accept”三部曲。要实现多人同时在线必须使用多线程或多进程。八、课后作业文件传输助手编写一个 Server 和 Client。Client 读取本地一个图片文件通过 Socket 发送给 ServerServer 接收并保存为received.jpg。群聊系统升级完善上面的多人聊天室。维护一个全局的clients列表当一个用户说话时服务器遍历这个列表把消息send给除他以外的所有人。简易 HTTP 服务器编写一个 TCP Server 监听 80 端口。当浏览器访问http://127.0.0.1时接收浏览器发的请求并返回一段简单的 HTML 文本h1Hello Web/h1。这其实就是 Web 服务器的雏形下节预告Day 27HTTP 协议与 Requests 库- Socket 太底层了每次都要自己拼报文好累。明天我们学习应用层最常用的 HTTP 协议并用 Python 轻松抓取网页数据爬虫入门系列导航上一篇Day 25 - 多进程编程下一篇Day 27 - HTTP协议与Requests待更新