python实现简单的聊天小程序

article/2025/8/25 20:01:40

概要

这是一个使用python实现一个简单的聊天室的功能,里面包含群聊,私聊两种聊天方式.实现的方式是使用套接字编程的一个使用TCP协议 c/s结构的聊天室

实现思路

x01 服务端的建立

首先,在服务端,使用socket进行消息的接受,每接受一个socket的请求,就开启一个新的线程来管理消息的分发与接受,同时,又存在一个handler来管理所有的线程,从而实现对聊天室的各种功能的处理

x02 客户端的建立

客户端的建立就要比服务端简单多了,客户端的作用只是对消息的发送以及接受,以及按照特定的规则去输入特定的字符从而实现不同的功能的使用,因此,在客户端这里,只需要去使用两个线程,一个是专门用于接受消息,一个是专门用于发送消息的

至于为什么不用一个呢,那是因为,只用一个的话,当接受了消息,在发送之前接受消息的处于阻塞状态,同理,发送消息也是,那么要是将这两个功能放在一个地方实现,就会导致没有办法连续发送或者接受消息了

实现方式

服务端实现

服务端类图
服务端流程图

import json
import threading
from socket import *
from time import ctimeclass PyChattingServer:__socket = socket(AF_INET, SOCK_STREAM, 0)__address = ('', 12231)__buf = 1024def __init__(self):self.__socket.bind(self.__address)self.__socket.listen(20)self.__msg_handler = ChattingHandler()def start_session(self):print('等待客户连接...\r\n')try:while True:cs, caddr = self.__socket.accept()# 利用handler来管理线程,实现线程之间的socket的相互通信self.__msg_handler.start_thread(cs, caddr)except socket.error:passclass ChattingThread(threading.Thread):__buf = 1024def __init__(self, cs, caddr, msg_handler):super(ChattingThread, self).__init__()self.__cs = csself.__caddr = caddrself.__msg_handler = msg_handler# 使用多线程管理会话def run(self):try:print('...连接来自于:', self.__caddr)data = '欢迎你到来PY_CHATTING!请输入你的很cooooool的昵称(不能带有空格哟`)\r\n'self.__cs.sendall(bytes(data, 'utf-8'))while True:data = self.__cs.recv(self.__buf).decode('utf-8')if not data:breakself.__msg_handler.handle_msg(data, self.__cs)print(data)except socket.error as e:print(e.args)passfinally:self.__msg_handler.close_conn(self.__cs)self.__cs.close()class ChattingHandler:__help_str = "[ SYSTEM ]\r\n" \"输入/ls,即可获得所有登陆用户信息\r\n" \"输入/h,即可获得帮助\r\n" \"输入@用户名 (注意用户名后面的空格)+消息,即可发动单聊\r\n" \"输入/i,即可屏蔽群聊信息\r\n" \"再次输入/i,即可取消屏蔽\r\n" \"所有首字符为/的信息都不会发送出去"__buf = 1024__socket_list = []__user_name_to_socket = {}__socket_to_user_name = {}__user_name_to_broadcast_state = {}def start_thread(self, cs, caddr):self.__socket_list.append(cs)chat_thread = ChattingThread(cs, caddr, self)chat_thread.start()def close_conn(self, cs):if cs not in self.__socket_list:return# 去除socket的记录nickname = "SOMEONE"if cs in self.__socket_list:self.__socket_list.remove(cs)# 去除socket与username之间的映射关系if cs in self.__socket_to_user_name:nickname = self.__socket_to_user_name[cs]self.__user_name_to_socket.pop(self.__socket_to_user_name[cs])self.__socket_to_user_name.pop(cs)self.__user_name_to_broadcast_state.pop(nickname)nickname += " "# 广播某玩家退出聊天室self.broadcast_system_msg(nickname + "离开了PY_CHATTING")# 管理用户输入的信息def handle_msg(self, msg, cs):js = json.loads(msg)if js['type'] == "login":if js['msg'] not in self.__user_name_to_socket:if ' ' in js['msg']:self.send_to(json.dumps({'type': 'login','success': False,'msg': '账号不能够带有空格'}), cs)else:self.__user_name_to_socket[js['msg']] = csself.__socket_to_user_name[cs] = js['msg']self.__user_name_to_broadcast_state[js['msg']] = Trueself.send_to(json.dumps({'type': 'login','success': True,'msg': '昵称建立成功,输入/ls可查看所有在线的人,输入/help可以查看帮助(所有首字符为/的消息都不会发送)'}), cs)# 广播其他人,他已经进入聊天室self.broadcast_system_msg(js['msg'] + "已经进入了聊天室")else:self.send_to(json.dumps({'type': 'login','success': False,'msg': '账号已存在'}), cs)# 若玩家处于屏蔽模式,则无法发送群聊消息elif js['type'] == "broadcast":if self.__user_name_to_broadcast_state[self.__socket_to_user_name[cs]]:self.broadcast(js['msg'], cs)else:self.send_to(json.dumps({'type': 'broadcast','msg': '屏蔽模式下无法发送群聊信息'}), cs)elif js['type'] == "ls":self.send_to(json.dumps({'type': 'ls','msg': self.get_all_login_user_info()}), cs)elif js['type'] == "help":self.send_to(json.dumps({'type': 'help','msg': self.__help_str}), cs)elif js['type'] == "sendto":self.single_chatting(cs, js['nickname'], js['msg'])elif js['type'] == "ignore":self.exchange_ignore_state(cs)def exchange_ignore_state(self, cs):if cs in self.__socket_to_user_name:state = self.__user_name_to_broadcast_state[self.__socket_to_user_name[cs]]if state:state = Falseelse:state = Trueself.__user_name_to_broadcast_state.pop(self.__socket_to_user_name[cs])self.__user_name_to_broadcast_state[self.__socket_to_user_name[cs]] = stateif self.__user_name_to_broadcast_state[self.__socket_to_user_name[cs]]:msg = "通常模式"else:msg = "屏蔽模式"self.send_to(json.dumps({'type': 'ignore','success': True,'msg': '[TIME : %s]\r\n[ SYSTEM ] : %s\r\n' % (ctime(), "模式切换成功,现在是" + msg)}), cs)else:self.send_to({'type': 'ignore','success': False,'msg': '切换失败'}, cs)def single_chatting(self, cs, nickname, msg):if nickname in self.__user_name_to_socket:msg = '[TIME : %s]\r\n[ %s CHATTING TO %s ] : %s\r\n' % (ctime(), self.__socket_to_user_name[cs], nickname, msg)self.send_to_list(json.dumps({'type': 'single','msg': msg}), self.__user_name_to_socket[nickname], cs)else:self.send_to(json.dumps({'type': 'single','msg': '该用户不存在'}), cs)print(nickname)def send_to_list(self, msg, *cs):for i in range(len(cs)):self.send_to(msg, cs[i])def get_all_login_user_info(self):login_list = "[ SYSTEM ] ALIVE USER : \r\n"for key in self.__socket_to_user_name:login_list += self.__socket_to_user_name[key] + ",\r\n"return login_listdef send_to(self, msg, cs):if cs not in self.__socket_list:self.__socket_list.append(cs)cs.sendall(bytes(msg, 'utf-8'))def broadcast_system_msg(self, msg):data = '[TIME : %s]\r\n[ SYSTEM ] : %s\r\n' % (ctime(), msg)js = json.dumps({'type': 'system_msg','msg': data})# 屏蔽了群聊的玩家也可以获得系统的群发信息for i in range(len(self.__socket_list)):if self.__socket_list[i] in self.__socket_to_user_name:self.__socket_list[i].sendall(bytes(js, 'utf-8'))def broadcast(self, msg, cs):data = '[TIME : %s]\r\n[%s] : %s\r\n' % (ctime(), self.__socket_to_user_name[cs], msg)js = json.dumps({'type': 'broadcast','msg': data})# 没有的登陆的玩家无法得知消息,屏蔽了群聊的玩家也没办法获取信息for i in range(len(self.__socket_list)):if self.__socket_list[i] in self.__socket_to_user_name \and self.__user_name_to_broadcast_state[self.__socket_to_user_name[self.__socket_list[i]]]:self.__socket_list[i].sendall(bytes(js, 'utf-8'))def main():server = PyChattingServer()server.start_session()main()

客户端的实现

客户端类图
客户端流程图

import json
import threading
from socket import *is_login = False
is_broadcast = Trueclass ClientReceiveThread(threading.Thread):__buf = 1024def __init__(self, cs):super(ClientReceiveThread, self).__init__()self.__cs = csdef run(self):self.receive_msg()def receive_msg(self):while True:msg = self.__cs.recv(self.__buf).decode('utf-8')if not msg:breakjs = json.loads(msg)if js['type'] == "login":if js['success']:global is_loginis_login = Trueprint(js['msg'])elif js['type'] == "ignore":if js['success']:global is_broadcastif is_broadcast:is_broadcast = Falseelse:is_broadcast = Trueprint(js['msg'])else:if not is_broadcast:print("[现在处于屏蔽模式]")print(js['msg'])class ClientSendMsgThread(threading.Thread):def __init__(self, cs):super(ClientSendMsgThread, self).__init__()self.__cs = csdef run(self):self.send_msg()# 根据不同的输入格式来进行不同的聊天方式def send_msg(self):while True:js = Nonemsg = input()if not is_login:js = json.dumps({'type': 'login','msg': msg})elif msg[0] == "@":data = msg.split(' ')if not data:print("请重新输入")breaknickname = data[0]nickname = nickname.strip("@")if len(data) == 1:data.append(" ")js = json.dumps({'type': 'sendto','nickname': nickname,'msg': data[1]})elif msg == "/help":js = json.dumps({'type': 'help','msg': None})elif msg == "/ls":js = json.dumps({'type': 'ls','msg': None})elif msg == "/i":js = json.dumps({'type': 'ignore','msg': None})else:if msg[0] != '/':js = json.dumps({'type': 'broadcast','msg': msg})if js is not None:self.__cs.sendall(bytes(js, 'utf-8'))def main():buf = 1024# 改变这个的地址,变成服务器的地址,那么只要部署到服务器上就可以全网使用了address = ("127.0.0.1", 12231)cs = socket(AF_INET, SOCK_STREAM, 0)cs.connect(address)data = cs.recv(buf).decode("utf-8")if data:print(data)receive_thread = ClientReceiveThread(cs)receive_thread.start()send_thread = ClientSendMsgThread(cs)send_thread.start()while True:passmain()

这样一个简单的聊天室就建立了

总结

在这个实现聊天室当中,我使用的是json格式的字符串信息来编写的协议,或许,也可以使用一些更加简单的方式去实现

其实这个聊天室也就是一个最基本的socket编程的实现方案,也是一些属于网络方面的比较简单的编写吧


http://chatgpt.dhexx.cn/article/XyXXwM5m.shtml

相关文章

微信小程序调出选择好友聊天窗口

微信小程序分享好友 点击分享,弹出层选择“分享给微信好友”,点击‘“分享给微信好友”,直接调出选择好友聊天窗口。 如图: 微信小程序API:onShareAppMessage 定义 onShareAppMessage 函数,设置该页面的…

小程序mqtt实现聊天功能

mqtt是什么? MQTT是一个轻量级传输协议,它被设计用于轻量级的发布/订阅式消息传输,MQTT协议针对低带宽网络,低计算能力的设备,做了特殊的优化。是一种简单、稳定、开放、轻量级易于实现的消息协议,在物联网…

微信小程序接入腾讯IM即时通讯,实现在线聊天

最近在帮朋友写一个二手交易平台,买卖双方在线沟通的功能(类似于某鱼) 先上传做完的效果图,后续再更新源码,目前实现了消息列表显示未读数量,显示最后一条信息内容,收到信息后刷新列表。聊天页面 不要吐槽…

应用实战|微信小程序开发示例--多人聊天互动空间

“超能力”数据库~拿来即用,应用开发人员再也不用为撰写API而发愁。MemFire Cloud 为开发者提供了简单易用的云数据库(表编辑器、自动生成API、SQL编辑器、备份恢复、托管运维),很大地降低开发者的使用门槛。 本示例是…

微信小程序实现websocket及单人聊天功能

一、什么是websocket: WebSocket是HTML5下一种新的协议(websocket协议本质上是一个基于tcp的协议)它实现了浏览器与服务器全双工通信,能更好的节省服务器资源和带宽并达到实时通讯的目的Websocket是一个持久化的协议 二、websoc…

uni-app+websocket实现语音聊天小程序

uni-appwebsocket 开发语音聊天咨询小程序

微信小程序中百分百实现聊天界面

众所周知,全网来看,微信的聊天界面看着就是舒服,那能否在微信小程序中实现该功能,同时可以实现输入文本和语音功能,而且在输入文本时,键盘可以弹起。话不多说,上界面看看。 wxml实现如下: <view> <scroll-view scroll-y scroll-into-view={{toView}} style=h…

图灵聊天机器人小程序

历时半年整理出了十多万字的学习笔记&#xff0c;目前依旧在更新 欢迎点赞和支持&#xff5e;&#x1f973;&#x1f973;&#x1f973; 博客 项目描述&#xff1a; 根据图灵API向聊天机器人发送聊天信息&#xff0c;并渲染返回的数据。具有清空聊天记录的按钮。本来是想上线…

微信小程序-模仿绘制聊天界面

参考文章 1、小程序模仿微信聊天界面 2、微信小程序实现仿微信聊天界面(各种细节处理) 3、微信小程序之页面中关于聊天框三角形的制作和使用 4、仿微信聊天记录时间显示 5、微信小程序-同时获取麦克风、相机权限、获取多个权限 6、【uni-app】模仿微信实现简易发送/取发语音功…

微信聊天小程序——(二、账号的注册与登录)

具体效果&#xff1a; 目录 二、账号的注册与登录 步骤一、获取用户信息 步骤二、用户输入账号密码&#xff08;在注册页面中&#xff09; 步骤三、将获取到的值放到我们的数据库中&#xff08;在注册页面中&#xff09; 步骤四、登录的页面逻辑 步骤五、登录页面的实现 …

微信聊天小程序——(三、获取好友列表)

三、获取好友列表 步骤一、展示所有好友的推荐列表&#xff08;friends页面&#xff09; 具体效果&#xff1a; 实现思路&#xff1a; 我们有我们的用户数据库表即&#xff1a;uers循环我们的数据库用户表&#xff0c;达到所有的用户信息&#xff0c;即&#xff1a;userLi…

微信聊天小程序——(五、添加好友)

五、添加好友 步骤一、通过搜索添加好友 具体效果&#xff1a; 思路&#xff1a; 本质上来讲&#xff0c;就是通过输入框得到好友账号信息&#xff0c;之后再数据库中查询&#xff0c;最后返回并渲染查询结果。首先&#xff0c;得到输入框的值&#xff0c;并传递到我们的页面…

支付宝小程序平台的IM聊天插件

文章目录 前言一、用户端1.基本展示2.难处理的点二、另一用户端1.前端websocket的整合2.手机息屏websocket断线问题2.websocket服务端配置3.后端整合websocket作为服务端&#xff0c;传输消息给前端 总结 前言 最近工作需求来了个项目&#xff0c;前景为在支付宝平台上发布一个…

使用 Python 编写一个聊天小程序

欢迎关注 “小白玩转Python”&#xff0c;发现更多 “有趣” 本篇文章分享如何用相当简洁的 Python 代码制作一个简单的聊天应用程序。更重要的是&#xff0c;我已经实现了没有任何第三方依赖的代码&#xff01; 首先&#xff0c;我创建了一个聊天服务器&#xff0c;通过它可以…

小米手机解BL锁教程

1.找到设置&#xff0c;找到我的设备 2.点击全部参数&#xff0c;多点几下miui版本&#xff0c;直到弹出开发者模式提醒。 3.返回&#xff0c;找到更多设置 4.找到开发者选项 5.找到设备定状态 6.绑定账号和设备&#xff0c;关机&#xff0c;按开键加音量减&#xff0c;进去fas…

安卓搞机玩机-什么是“锁 ” BL锁 屏幕锁 账号锁 设备锁等分析

相信把玩安卓机型的友友们都大概了解机型的锁是什么概念。但有些友友可能还分不清楚具体锁的概念。今天这个帖子由浅入深的带你了解安卓机型中各种“锁”的概念.这类话题比较敏感。只是大概带你分清楚锁的分类和基本对应的解锁方式. 一.屏幕锁【 图案锁 指纹锁 数字锁 人…

万能小米手机解锁,刷机,默认破解BL锁

写在第一条:下载之前请注意 本软件不支持最新机型,只支持4代和4代以前的机型,请注意 早就想给自己的小米手机刷机了&#xff0c;奈何一直没有门&#xff0c;最后还在求助了万能的淘宝&#xff0c;刚刚在淘宝花了 30大洋买的刷机工具&#xff0c;刷机成功之后&#xff0c;才反…

xiaomi 小米 红米redmi 秒解锁BL锁,不用等,在线秒解锁BL工具介绍

xiaomi 小米 红米redmi 秒解锁BL锁,不用等&#xff0c;在线秒解锁BL Xlaomi Redmi K40 Gaming Xlaomt Poco F3 GT Gaming Xaoml Poco X3 GT Xaoml Redmi Note9 5G Xlaomi Redml Note 10 Pro 5G Xlaoml Redmi Note 10 5G Xlaoml Redml Note 10T 5G Xlaoml Poco M3 Pro 5G Xaoml…

小米手机解BL锁、线刷详细教程,适用于小米全系列手机

[教程] 小米手机解BL锁、线刷详细教程&#xff0c;适用于小米全系列手机 这几天看到论坛里很多人在问怎么线刷&#xff0c;下面我就做个详细的线教程大家看一下高手别喷我哈 此教程只适合刷官方MIUI包 进入正题。 第一步&#xff1a;解BL锁 1.浏览器打开申请解锁小米手机点击立…

android@解bl锁@twrp的刷入和使用问题

文章目录 解bl锁步骤 附:MIUI线刷工具待线刷设备扫面和检查使用方式线刷工具卡住的关闭方法 第三方recoverytwrp解密datadata decrypt清除data后用twrp中刷入文件刷入面具 如何找到合适的TWRP rec ref 解bl锁 不是所有android设备都支持解锁下面是以最为典型的MIUI android设备…