Python 简易即时通讯
2026/9/20 15:55:56 网站建设 项目流程

Python 简易即时通讯(IM)

使用socket + threading实现C/S架构(服务端 + 客户端),纯标准库,不需要额外pip安装第三方包

原理:TCP长连接;服务端负责转发消息,客户端可以收发消息,支持多人聊天。
分为两个文件:server.py(服务端)、client.py(客户端)
每行代码详细注释。

1. server.py 服务端代码

# 导入socket模块:用于网络通信,创建TCP套接字importsocket# 导入threading多线程,同时处理多个客户端连接importthreading# -------------------------- 配置常量 --------------------------# 监听地址,0.0.0.0代表监听本机所有网卡HOST="0.0.0.0"# 端口号,选一个不被占用端口,范围1024~65535PORT=8888# 保存所有客户端连接,key:客户端socket,value:用户名client_list={}# 线程锁,防止多线程同时修改client_list造成并发冲突lock=threading.Lock()defbroadcast(msg,sender_socket=None):""" 广播函数:把一条消息发给所有在线客户端 msg: 要发送的字节消息 sender_socket: 发送者socket,不发给自己 """# 遍历所有在线客户端withlock:forcli_sockinclient_list:# 不发送给消息发送人ifcli_sock!=sender_socket:try:cli_sock.send(msg)exceptException:# 如果发送失败,说明客户端掉线,关闭socketcli_sock.close()delclient_list[cli_sock]defhandle_client(client_sock,client_addr):""" 单独线程:处理单个客户端所有消息收发 client_sock: 客户端socket对象 client_addr: (ip,端口)客户端地址 """print(f"新客户端接入:{client_addr}")username=""try:# 第一次接收:客户端发送用户名username=client_sock.recv(1024).decode("utf-8")# 加锁,添加到在线用户列表withlock:client_list[client_sock]=username# 广播:xxx上线join_msg=f"【系统消息】用户{username}上线了".encode("utf-8")broadcast(join_msg)# 持续循环接收客户端发来消息whileTrue:# recv阻塞等待接收数据,最大接收1024字节data=client_sock.recv(1024)# 如果data为空,表示客户端断开连接ifnotdata:break# 拼接消息格式:【用户名】消息内容recv_text=data.decode("utf-8")send_msg=f"【{username}{recv_text}".encode("utf-8")# 广播给所有人broadcast(send_msg,client_sock)exceptExceptionase:print(f"客户端{client_addr}异常断开:{e}")finally:# 用户下线清理工作client_sock.close()withlock:# 如果用户在列表中,删除ifclient_sockinclient_list:delclient_list[client_sock]# 广播下线通知leave_msg=f"【系统消息】用户{username}下线了".encode("utf-8")broadcast(leave_msg)print(f"客户端{client_addr}已断开")defstart_server():"""启动服务端主函数"""# 创建TCP套接字,AF_INET IPv4,SOCK_STREAM TCP协议server_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)# 设置端口复用,程序重启可以快速重用端口server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)# 绑定IP和端口server_socket.bind((HOST,PORT))# 开始监听,最大挂起连接数5server_socket.listen(5)print(f"服务端启动成功,监听端口:{PORT},等待客户端连接...")# 循环不断接收新客户端连接whileTrue:# accept阻塞等待客户端接入,返回客户端socket+地址cli_sock,cli_addr=server_socket.accept()# 创建新线程处理这个客户端,守护线程t=threading.Thread(target=handle_client,args=(cli_sock,cli_addr),daemon=True)# 启动线程t.start()# 打印当前在线人数print(f"当前在线人数:{threading.active_count()-1}")# 程序入口if__name__=="__main__":start_server()

2. client.py 客户端代码

importsocketimportthreading# -------------------------- 配置 --------------------------# 服务端IP,如果本地测试填127.0.0.1;局域网则填写运行server机器的内网ipSERVER_HOST="127.0.0.1"SERVER_PORT=8888defrecv_msg(sock):"""接收消息的线程:持续监听服务端广播的消息"""whileTrue:try:# 接收服务端转发的消息msg=sock.recv(1024).decode("utf-8")# 打印收到消息print(msg)exceptException:print("与服务端断开连接!")sock.close()breakdefstart_client():"""启动客户端"""# 创建TCP socketclient_sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)# 连接服务端client_sock.connect((SERVER_HOST,SERVER_PORT))# 输入用户名username=input("请输入你的用户名:")# 把用户名发送给服务端client_sock.send(username.encode("utf-8"))# 创建接收消息子线程,后台持续接收消息recv_thread=threading.Thread(target=recv_msg,args=(client_sock,),daemon=True)recv_thread.start()print("==== 聊天已开启,输入消息回车发送,输入exit退出 ====")# 主线程负责读取控制台输入、发送消息whileTrue:text=input()# 输入exit退出聊天iftext.lower()=="exit":client_sock.close()break# 将输入文本编码发送给服务端client_sock.send(text.encode("utf-8"))if__name__=="__main__":start_client()

使用步骤

  1. 打开第一个终端,运行服务端
python server.py
  1. 打开多个新终端,分别运行客户端
python client.py
  1. 输入用户名,就可以多人聊天
  2. 输入exit退出客户端

功能说明

✅ 多人在线群聊
✅ 用户上线/下线系统提示
✅ 消息广播,所有人看到别人发的消息
✅ 多线程并发,互不阻塞
✅ 异常掉线自动处理

局限性(面试可以主动说,体现工程思考)

  1. 群聊,没有私聊功能
  2. 纯控制台,没有GUI界面
  3. 没有消息持久化(关闭程序消息丢失,无数据库)
  4. 没有用户登录密码校验
  5. 没有图片/文件传输,仅文本消息
  6. 简单编码,没有加密传输(明文传输,不安全)
  7. 粘包问题未处理(长消息会出现分包/粘包)

面试可讲的扩展思路

  1. 增加私聊:消息增加接收人标识,服务端判断是广播还是单发
  2. GUI:tkinter / PyQt 图形界面
  3. 消息持久化:sqlite保存聊天记录
  4. 加密:使用ssl套接字,或者AES加密消息
  5. 文件传输:增加文件二进制读写,分片传输
  6. 解决TCP粘包:消息头部增加消息长度

可选扩展需求

你可以选一个方向,我继续写:

  1. 增加私聊功能
  2. 改成tkinter图形界面IM软件
  3. 增加文件发送功能
  4. 讲解TCP粘包改造代码

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询