
Python 简易即时通讯IM使用socket threading实现C/S架构服务端 客户端纯标准库不需要额外pip安装第三方包。原理TCP长连接服务端负责转发消息客户端可以收发消息支持多人聊天。分为两个文件server.py服务端、client.py客户端每行代码详细注释。1. server.py 服务端代码# 导入socket模块用于网络通信创建TCP套接字importsocket# 导入threading多线程同时处理多个客户端连接importthreading# -------------------------- 配置常量 --------------------------# 监听地址0.0.0.0代表监听本机所有网卡HOST0.0.0.0# 端口号选一个不被占用端口范围1024~65535PORT8888# 保存所有客户端连接key客户端socketvalue用户名client_list{}# 线程锁防止多线程同时修改client_list造成并发冲突lockthreading.Lock()defbroadcast(msg,sender_socketNone): 广播函数把一条消息发给所有在线客户端 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})usernametry:# 第一次接收客户端发送用户名usernameclient_sock.recv(1024).decode(utf-8)# 加锁添加到在线用户列表withlock:client_list[client_sock]username# 广播xxx上线join_msgf【系统消息】用户{username}上线了.encode(utf-8)broadcast(join_msg)# 持续循环接收客户端发来消息whileTrue:# recv阻塞等待接收数据最大接收1024字节dataclient_sock.recv(1024)# 如果data为空表示客户端断开连接ifnotdata:break# 拼接消息格式【用户名】消息内容recv_textdata.decode(utf-8)send_msgf【{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_msgf【系统消息】用户{username}下线了.encode(utf-8)broadcast(leave_msg)print(f客户端{client_addr}已断开)defstart_server():启动服务端主函数# 创建TCP套接字AF_INET IPv4SOCK_STREAM TCP协议server_socketsocket.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_addrserver_socket.accept()# 创建新线程处理这个客户端守护线程tthreading.Thread(targethandle_client,args(cli_sock,cli_addr),daemonTrue)# 启动线程t.start()# 打印当前在线人数print(f当前在线人数{threading.active_count()-1})# 程序入口if__name____main__:start_server()2. client.py 客户端代码importsocketimportthreading# -------------------------- 配置 --------------------------# 服务端IP如果本地测试填127.0.0.1局域网则填写运行server机器的内网ipSERVER_HOST127.0.0.1SERVER_PORT8888defrecv_msg(sock):接收消息的线程持续监听服务端广播的消息whileTrue:try:# 接收服务端转发的消息msgsock.recv(1024).decode(utf-8)# 打印收到消息print(msg)exceptException:print(与服务端断开连接)sock.close()breakdefstart_client():启动客户端# 创建TCP socketclient_socksocket.socket(socket.AF_INET,socket.SOCK_STREAM)# 连接服务端client_sock.connect((SERVER_HOST,SERVER_PORT))# 输入用户名usernameinput(请输入你的用户名)# 把用户名发送给服务端client_sock.send(username.encode(utf-8))# 创建接收消息子线程后台持续接收消息recv_threadthreading.Thread(targetrecv_msg,args(client_sock,),daemonTrue)recv_thread.start()print( 聊天已开启输入消息回车发送输入exit退出 )# 主线程负责读取控制台输入、发送消息whileTrue:textinput()# 输入exit退出聊天iftext.lower()exit:client_sock.close()break# 将输入文本编码发送给服务端client_sock.send(text.encode(utf-8))if__name____main__:start_client()使用步骤打开第一个终端运行服务端python server.py打开多个新终端分别运行客户端python client.py输入用户名就可以多人聊天输入exit退出客户端功能说明✅ 多人在线群聊✅ 用户上线/下线系统提示✅ 消息广播所有人看到别人发的消息✅ 多线程并发互不阻塞✅ 异常掉线自动处理局限性面试可以主动说体现工程思考仅群聊没有私聊功能纯控制台没有GUI界面没有消息持久化关闭程序消息丢失无数据库没有用户登录密码校验没有图片/文件传输仅文本消息简单编码没有加密传输明文传输不安全粘包问题未处理长消息会出现分包/粘包面试可讲的扩展思路增加私聊消息增加接收人标识服务端判断是广播还是单发GUItkinter / PyQt 图形界面消息持久化sqlite保存聊天记录加密使用ssl套接字或者AES加密消息文件传输增加文件二进制读写分片传输解决TCP粘包消息头部增加消息长度可选扩展需求你可以选一个方向我继续写增加私聊功能改成tkinter图形界面IM软件增加文件发送功能讲解TCP粘包改造代码