news 2026/4/22 17:13:25

Day 26:【99天精通Python】网络编程入门 (Socket) - 让电脑互相“打电话“

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Day 26:【99天精通Python】网络编程入门 (Socket) - 让电脑互相“打电话“

Day 26:【99天精通Python】网络编程入门 (Socket) - 让电脑互相"打电话"

前言

欢迎来到第26天!

在此之前,我们的程序都只是在自己的电脑上自言自语(单机版)。但互联网的魅力在于互联互通。通过网络编程,我们可以让运行在不同电脑(甚至不同国家)上的程序进行数据交换。

比如:浏览网页(浏览器 <-> 服务器)、玩在线游戏(客户端 <-> 游戏服务器)、聊天软件(你 <-> 腾讯服务器 <-> 朋友)。

今天,我们将学习网络编程的基石——Socket(套接字),并亲手编写一个聊天程序,让两台程序能够隔空对话。

本节内容:

  • 网络基础:IP、端口、TCP/UDP
  • Socket 通信流程
  • 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_socket=socket.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,addr=server_socket.accept()print(f"客户端{addr}已连接!")# 5. 接收与发送数据whileTrue:# recv(1024): 一次最多接收 1024 字节data=client_sock.recv(1024)ifnotdata:# 客户端断开连接print("客户端已断开。")breakmsg=data.decode('utf-8')# 解码print(f"收到消息:{msg}")# 回复消息 (编码为 bytes)response=f"服务端收到:{msg}"client_sock.send(response.encode('utf-8'))# 6. 关闭连接client_sock.close()server_socket.close()

3.2 TCP 客户端 (Client.py)

importsocket# 1. 创建 Socketclient_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)# 2. 连接服务器 (IP, Port)# 如果服务器在另一台电脑,这里填那台电脑的 IPclient_socket.connect(('127.0.0.1',8888))whileTrue:msg=input("请输入发送内容 (q退出): ")ifmsg=='q':break# 3. 发送数据client_socket.send(msg.encode('utf-8'))# 4. 接收回复recv_data=client_socket.recv(1024)print(recv_data.decode('utf-8'))# 5. 关闭client_socket.close()

运行方式

  1. 先运行Server.py,看到"服务器启动"。
  2. 再运行Client.py
  3. 在客户端输入文字,观察服务器的反应。

四、UDP 编程简介

UDP 不需要建立连接,没有listenaccept,上来直接发,简单粗暴。

4.1 UDP 服务器

importsocket# SOCK_DGRAM 代表 UDPudp_server=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)udp_server.bind(('0.0.0.0',9999))print("UDP 服务器启动...")whileTrue:# recvfrom 返回 (数据, (ip, port))data,addr=udp_server.recvfrom(1024)print(f"来自{addr}的消息:{data.decode()}")

4.2 UDP 客户端

importsocket udp_client=socket.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:data=client_sock.recv(1024)ifnotdata:breakmsg=data.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():server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)server.bind(('0.0.0.0',8888))server.listen(10)# 允许10人排队print("多人聊天服务器启动...")whileTrue:# 主线程只负责接待client,addr=server.accept()# 创建分身(线程)去专门服务这个用户t=threading.Thread(target=handle_client,args=(client,addr))t.start()if__name__=='__main__':main()

六、常见问题

Q1:为什么接收/发送都要 encode/decode?

网络传输的底层是字节流 (bytes),不是字符串 (string)

  • 发送前:字符串 -> bytes (encode)
  • 接收后:bytes -> 字符串 (decode)

Q2:端口被占用 (Address already in use) 怎么办?

程序非正常退出时,端口可能没释放。

  1. 等一分钟再试(操作系统会自动回收)。
  2. 代码中添加setsockopt允许端口复用(在 bind 之前):
    server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)

Q3:TCP 粘包问题?

TCP 是流式协议,你发了 “A” 和 “B”,接收端可能一次性收到 “AB”。
解决办法:设计应用层协议,比如每条消息前加上长度头(先发4个字节表示消息长度,再发消息体)。


七、小结

网络编程 Socket

TCP (可靠)

UDP (快速)

Server: bind -> listen -> accept

Client: connect

send / recv

无连接

sendto / recvfrom

并发处理

Socket + Threading

主线程 accept

子线程 recv

关键要点

  1. TCP是打电话(连接、可靠),UDP是广播(无连接、不可靠)。
  2. Socket是通信的端点,由 IP 和端口组成。
  3. 写服务器时,记住“bind -> listen -> accept”三部曲。
  4. 要实现多人同时在线,必须使用多线程或多进程。

八、课后作业

  1. 文件传输助手:编写一个 Server 和 Client。Client 读取本地一个图片文件,通过 Socket 发送给 Server;Server 接收并保存为received.jpg
  2. 群聊系统升级:完善上面的多人聊天室。维护一个全局的clients列表,当一个用户说话时,服务器遍历这个列表,把消息send除他以外的所有人。
  3. 简易 HTTP 服务器:编写一个 TCP Server 监听 80 端口。当浏览器访问http://127.0.0.1时,接收浏览器发的请求,并返回一段简单的 HTML 文本<h1>Hello Web</h1>。(这其实就是 Web 服务器的雏形!)

下节预告

Day 27:HTTP 协议与 Requests 库- Socket 太底层了,每次都要自己拼报文好累。明天我们学习应用层最常用的 HTTP 协议,并用 Python 轻松抓取网页数据(爬虫入门)!


系列导航

  • 上一篇:Day 25 - 多进程编程
  • 下一篇:Day 27 - HTTP协议与Requests(待更新)
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/17 16:02:22

天猫TP公司是什么意思?一般提供哪些服务?

在电商行业的发展进程中&#xff0c;天猫平台作为国内领先的电商巨头&#xff0c;吸引了众多品牌和商家的入驻。为了帮助品牌方更好地运营天猫店铺&#xff0c;提高店铺的竞争力和业绩&#xff0c;天猫TP公司应运而生。天猫TP公司凭借其专业的运营能力和丰富的资源优势&#xf…

作者头像 李华
网站建设 2026/4/18 21:18:42

解析USB3.0接口定义引脚说明中的盲埋孔使用技巧

从USB3.0引脚定义看高速PCB设计&#xff1a;盲埋孔为何是信号完整性的“隐形推手”&#xff1f;你有没有遇到过这样的情况&#xff1f;明明严格按照USB3.0规范布线&#xff0c;差分对也做了等长匹配&#xff0c;参考平面也没分割——可测试时眼图就是打不开&#xff0c;误码率居…

作者头像 李华
网站建设 2026/4/19 20:30:02

微服务分布式SpringBoot+Vue+Springcloud社区安全智慧消防管理系统

目录社区安全智慧消防管理系统摘要开发技术源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;社区安全智慧消防管理系统摘要 该系统基于微服务分布式架构&#xff0c;采用SpringBoot、Vue.js和SpringCloud技术栈&#xff0c;旨在构建高效…

作者头像 李华
网站建设 2026/4/21 12:35:43

Blazor Web App 在 IIS 部署的基路径设置

引言 在使用 Blazor Web App 进行开发时&#xff0c;部署到 IIS 服务器是一个常见的选择。然而&#xff0c;许多开发者在部署过程中可能会遇到一些配置问题&#xff0c;特别是在处理基路径&#xff08;Base Path&#xff09;设置时。本文将详细介绍如何正确设置 Blazor Web Ap…

作者头像 李华