一个聊天室,由两个部分组成。服务端和客户端。服务端接收客户端发来的消息,并将接收到的消息发送给其他客户端。客户端负责发送消息到服务端,并接收来自服务端发送的来自其他客户端的消息。

示例图(服务端和客户端):

这是属于一个群聊的聊天室,服务端会把每一条消息发送给所有客户端。当有人连接服务端或退出聊天时,所有在线的客户端都会收到提醒。

服务端源码:

# encoding: utf-8
import socket
import threading
import time
import sys
import json
import configparser as conf
import redis# redis.StrictRedis
r = redis.Redis(host='127.0.0.1', port=6379, db=1, decode_responses=True)cf = conf.ConfigParser()
cf.read('Server_Socket.ini')
socket_host = cf.get("socket", "host")
socket_port = cf.get("socket", "port")clients = set()
clients_lock = threading.Lock()global data_typedef socket_service():global data_typetry:s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)s.bind((socket_host, int(socket_port)))s.listen(100)except socket.error as msg:print(msg)sys.exit(1)print('等待客户端连接')while True:conn, addr = s.accept()try:data_type = json.loads(conn.recv(1024).decode("utf8"))except Exception as e:print(e)WelcomeClient = {"UserSum": 0, "text": "欢迎加入慕公子的聊天室!", "type": "client"}conn.send(bytes(json.dumps(WelcomeClient), "UTF-8"))if r.exists(data_type['Name']) == 0:r.set(str(addr), data_type['Name'])r.set(data_type['Name'], str(addr))if data_type['type'] == 'server':with clients_lock:clients.add(conn)for c in clients:if data_type['type'] == "server":try:sums = len(clients)dataClient = {"UserSum": sums, "text": data_type['text'], "type": "change"}c.send(bytes(json.dumps(dataClient), "UTF-8"))except ConnectionResetError as e:print(e)t = threading.Thread(target=deal_data, args=(conn, addr))t.start()elif r.exists(data_type['Name']) == 1:sums = len(clients)data1Client = {"UserSum": sums, "text": "名字重复,换一个名字吧。", "type": "client"}conn.send(bytes(json.dumps(data1Client), "UTF-8"))def deal_data(conn, addr):print(f'有新的客户端连接:{conn}-{addr}')try:while True:data = conn.recv(1024).decode("utf8")msg = json.loads(data)print(f"{addr}-{msg['Name']} 发送的消息:{msg['text']}")time.sleep(0.3)if data == 'exit' or not data:print(f'{addr} connection close')conn.send(bytes('Connection closed!'), 'UTF-8')breakwith clients_lock:for c in clients:if msg['type'] == "client":sums = len(clients)dataClient = {"UserSum": sums, "text": f"{msg['Name']} 发送的消息:{msg['text']}", "type": "client"}text = bytes(json.dumps(dataClient), "UTF-8")c.send(text)except ConnectionResetError as e:clients.remove(conn)UserName = r.get(str(addr))clSums = len(clients)with clients_lock:for c in clients:changeClient = {"UserSum": clSums, "text": f"{UserName},退出聊天。", "type": "change"}text = bytes(json.dumps(changeClient), "UTF-8")c.send(text)print(f"{e}--{addr}--{UserName},退出聊天。")r.delete(str(addr))r.delete(UserName)except json.decoder.JSONDecodeError as e:print(e)conn.close()if __name__ == '__main__':socket_service()

客户端代码:

import socketimport tkinter as tk
import tkinter.font as tkFont
from tkinter.filedialog import askdirectory
import tkinter.messagebox
import tkinter.filedialog
from tkinter import ttk
import threading as thr
from tkinter import scrolledtext
import os
import json
import configparser as confwindow = tk.Tk()
window.title('MuChat')
# 获取屏幕宽高
sw = window.winfo_screenwidth()
sh = window.winfo_screenheight()
# 设置屏幕的宽和高
ww = 370
wh = 470
x = (sw - ww) / 2
y = (sh - wh) / 2
# 根据屏幕宽高来让程序居中
window.geometry("%dx%d+%d+%d" % (ww, wh, x, y))
fontStyle = tkFont.Font(family="Lucida Grande", size=15)
tk.Label(window, text="MuChat", font=fontStyle).pack()
# 设置frame容器
frame = tk.Frame(window, padx=3, pady=3)
frame.pack()
frame_left = tk.Frame(frame)
frame_right = tk.Frame(frame)
frame_left.pack(side='left')
frame_right.pack(side='right')global sdef SumChange(sumCa):global sumLasumLa = tk.Label(window, text=f"当前在线{int(sumCa)}人", font=fontStyle)sumLa.pack()def socket_client():cf = conf.ConfigParser()cf.read('Client_Socket.ini')socket_host = cf.get("socket", "host")socket_port = cf.get("socket", "port")global stry:s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.connect((socket_host, int(socket_port)))print(s)data_json = {"Name": yourName.get(), "text": f"欢迎{yourName.get()}的加入!", "type": "server"}data = json.dumps(data_json).encode()s.send(data)except socket.error as msg:print(msg)while True:message = s.recv(1024).decode('utf-8')  # ConnectionAbortedError# print(message)jsonData = json.loads(message)print(jsonData)if jsonData:scr.insert(tk.END, f"{jsonData['text']}\n\n")scr.see(tk.END)scr.update()if jsonData['type'] == 'change':sumLa.pack_forget()SumChange(jsonData['UserSum'])def thrSocket():en.focus_set()soc = thr.Thread(target=socket_client, daemon=True, args=())soc.start()yourName = tk.StringVar()
tk.Entry(frame_left, textvariable=yourName, width=30).pack(padx=5, pady=10)
tk.Button(frame_right, text='连接服务端', font=fontStyle, width=18, height=1, command=lambda: thrSocket()).pack(padx=3,pady=3)def send_socket_client():global sif (not yourMsg.get()) | (yourMsg.get() == ' '):tkinter.messagebox.showinfo(title='提示', message="你还未输入内容!")returndata_json = {"Name": yourName.get(), "text": yourMsg.get(), "type": "client"}yourMsg.set('')data = json.dumps(data_json).encode()s.send(data)def SendSocket():soc = thr.Thread(target=send_socket_client, daemon=True, args=())soc.start()def socket_cloase():s.close()def ReSend(e):SendSocket()def socket_ini():os.startfile("Client_Socket.ini")yourMsg = tk.StringVar()
en = tk.Entry(frame_left, textvariable=yourMsg, width=30)
en.pack(padx=5, pady=10)
en.bind('<Return>', ReSend)tk.Button(frame_right, text='发送消息', font=fontStyle, width=18, height=1, command=lambda: SendSocket()).pack(padx=3,pady=3)
fontStyleRadio = tkFont.Font(family="Lucida Grande", size=13)tk.Button(frame_left, text='编辑配置文件', font=fontStyle, width=18, height=1, command=lambda: socket_ini()).pack(padx=3,pady=3)tk.Button(frame_right, text='关闭连接', font=fontStyle, width=18, height=1, command=lambda: socket_cloase()).pack(padx=3,pady=3)
scr = scrolledtext.ScrolledText(window, width=30, height=13, font=("宋体", 13))
scr.pack()
sumLa = tk.Label(window, text=f"当前在线0人", font=fontStyle)
sumLa.pack()
window.mainloop()

python 使用socket建立小型聊天室相关推荐

  1. python+pysimplegui+socket开发登录聊天室

    目录 项目结构 服务器端 客户端 共有 代码 配置信息 服务器端 functions.py senddata.py server.py 客户端 cilpboard.py listening.py sp ...

  2. python socket 网络聊天室_Python基于Socket实现简单聊天室

    本文实例为大家分享了Python基于Socket实现简单聊天室,供大家参考,具体内容如下 服务端 #!/usr/bin/env python # -*- coding: utf-8 -*- # @Ti ...

  3. 使用Socket实现通信聊天室

    使用Socket实现通信聊天室 通信聊天室是一个比较酷的项目. 建立通信聊天室之前我们会想到这些问题: ①聊天室得要有一个发送窗口和一个接受窗口,如何在这两个窗口建立联系? ②如何发送信息并且接受信息 ...

  4. python简单的多人聊天室

    刚开始学习python,写了一个聊天室练练手. Server.py import socket,select,thread;host=socket.gethostname() port=5963 ad ...

  5. java socket编程聊天室_Java Socket通信之聊天室功能

    Java Socket通信之聊天室功能 发布时间:2020-10-17 14:36:00 来源:脚本之家 阅读:73 作者:LY_624 本文实例为大家分享了Java Socket聊天室功能的具体代码 ...

  6. Python编写多线程多人聊天室系统(Socket编程、tkinter组件使用)

    是Python作业的说,也是自己编写了好长时间,有几个地方实现的方法非常的傻,请见谅QwQ 代码包含详细注释. 与此同时如果想让这个聊天室也能被全国各地的同学使用的话也可以将这个程序部署到云服务器上! ...

  7. python socket 多人聊天室

    参考来源(其实我从上面复制了一点): Python 的 Socket 编程教程  http://www.oschina.net/question/12_76126 Python线程指南 http:// ...

  8. python基于udp的网络聊天室再用tkinter显示_Python实现网络聊天室的示例代码(支持多人聊天与私聊)...

    实验名称: 网络聊天室 功能: i. 掌握利用Socket进行编程的技术 ii. 掌握多线程技术,保证双方可以同时发送 iii. 建立聊天工具 iv. 可以和单人聊天 v. 可以和多个人同时进行聊天 ...

  9. Linux下socket多人聊天室

    目录 前言 一.聊天室的实验内容 二.逐个功能的简单分析 三.系统功能模块分解图 1.服务端功能模块图 2.客户端功能模块图 3.守护进程功能模块图 四.功能模块流程图 1.服务端流程图 2.客户端流 ...

最新文章

  1. java中的注解(二)
  2. MySQL和Linux试题_Linux运维必会的MySql题之(一)
  3. 火狐浏览器修改userAgent
  4. 北漂程序员边城的幸福生活
  5. NYOJ的水题--括号匹配问题
  6. MWeb建立静态网站/博客的基础教程
  7. 【C#设计模式——创建型模式】抽象工厂模式
  8. 初级商业数字营销师超级推荐
  9. 企业ad域管理教程,有哪些有效的AD域管理办法?
  10. 论文笔记-《深度卷积神经网络的发展及其在计算机视觉领域的应用》
  11. VS如何安装到电脑上
  12. 超级猪周期拐点未到,用“数”养猪的春天却已来?
  13. 第41课:Checkpoint彻底解密:Checkpoint的运行原理和源码实现彻底详解
  14. Nginx 上搭建PHP站 更改目录出现的错误:File not found、403 forbidden (13: Permission denied)
  15. 瘦客户端那些事 - 开篇
  16. SQL数据库损坏及恢复分析
  17. 剑麻的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  18. matlab fgoalattain,MATLAB多目标优化
  19. NFT的几种发行方式你都了解过吗?不同的发行方式有什么优缺点?
  20. spring异常java.lang.IllegalStateException

热门文章

  1. 网站换域名,老域名权重值能转到新网站吗?
  2. 获取html隐藏元素,js获取隐藏元素的宽高
  3. iOS 获取当前设备具体型号(当前支持到iPhone7/iPhone7P )、系统版本、电量、序列号、设备名称、应用相关信息获取等
  4. 如何用FM模型做召回模型
  5. 使用Koala编译LESS文件
  6. 实数取整写入文件(C语言文件篇)
  7. 强制关机带来的软件无法打开
  8. 关于python构造函数的重载
  9. docker run
  10. P3654 First Step (ファーストステップ)【暴力枚举】