Python实现网络图形化界面多人聊天室 - Windows
Python实现网络图形化界面多人聊天室 - Windows
项目名称:网络多人聊天室图形界面版本
项目思路:
server.py
服务端文件,主进程中,创建图形化界面,询问地址(主机名,端口),点击开始进入聊天室。
创建子进程,开始网络连接,使用select.select循环接收客户端连接请求,使用timeout不断检查与主进程间队列(multiprocessing.Queues)的情况
client.py
客户端文件,主进程中,创建图形化界面,询问地址(主机名,端口),点击开始以连接到客户端。
创建子进程,开始网络连接。
settings.py
默认设置
readme.txt
# settings.py
# 默认设置 HOST = "127.0.0.1"
PORT = 5555
ADDR = HOST, PORT def center(root, width=300, height=150):
# 设置窗口居中
screenWidth = root.winfo_screenwidth()
screenHeight = root.winfo_screenheight()
x = (screenWidth - width) / 2
y = (screenHeight - height) / 2
root.geometry("%dx%d+%d+%d" % (width, height, x, y))
settings.py
# server.py
# 服务端代码 from time import ctime
from multiprocessing import Process, Queue
from select import select
from socket import *
from settings import *
from tkinter import *
from tkinter.scrolledtext import ScrolledText
from tkinter import messagebox def main_gui():
# 主窗口
root = Tk() # 设置窗口居中
center(root) # 设置窗口其他属性
root.title("多人聊天室主窗口")
root.resizable(0, 0)
root.configure(bg="white")
# root.iconbitmap("python.ico") # 添加主机名(HOST)以及端口号(PORT)等输入框
pad = 10
Label(root, text="主机名(Host):").grid(row=0, column=0, padx=pad, pady=pad)
ent_host = Entry(root)
ent_host.insert(0, HOST)
ent_host.grid(row=0, column=1, padx=pad, pady=pad)
Label(root, text="端口号(Port):").grid(row=1, column=0, padx=pad, pady=pad)
ent_port = Entry(root)
ent_port.insert(0, PORT)
ent_port.grid(row=1, column=1, padx=pad, pady=pad) # 组件列表
widgets = {
"ent_host": ent_host,
"ent_port": ent_port
} # 添加确认按钮
btn_cfm = Button(root, text="新建网络聊天室", command=lambda:validate(root, widgets))
btn_cfm.grid(rowspan=2, columnspan=2, padx=pad, pady=pad) # 绑定事件
root.bind("<Return>", lambda event:validate(root, widgets)) # 主循环事件
root.mainloop() def validate(root, widgets):
# 确认按钮事件,检查是否输入有误
host, port = widgets["ent_host"].get(), widgets["ent_port"].get() # 如果端口号不是纯数字
try:
port = int(port)
except:
messagebox.showerror("错误", "端口号必须为数字!")
return # 弹出错误窗口
if not host or not port:
messagebox.showerror("错误", "主机名或端口不可为空!")
return # 有效地址
addr = (host, port) # 检查是否套接字成功
try:
server = socket(AF_INET, SOCK_STREAM)
server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
server.bind(addr)
server.listen(10)
except Exception as e:
messagebox.showerror("错误", f"无法在{addr}上生成套接字!")
print(e)
return
else:
# 生成两个队列
# queue负责在子进程中循环get主进程的信息
# queueu负责在父进程中循环get子进程的消息
queue = Queue()
queueu = Queue() # 生成子进程
process = Process(target=inet, args=(server, queue, queueu))
process.daemon = True
process.start() # 创建聊天室页面
chatroom_gui(root, queue, queueu) def chatroom_gui(r, queue, queueu):
# 聊天室页面
r.destroy()
root = Tk() # 设置窗口居中
center(root, 500, 500) # 最小化窗口
root.minsize(350, 350) # 菜单栏
menubar = Menu(root)
menubar.add_command(label="新建", command=None)
menubar.add_command(label="信息", command=None)
menubar.add_command(label="退出", command=root.destroy)
root.config(menu=menubar) # 文本框
text = ScrolledText(root)
text.pack(fill=BOTH) # 输入框
ent = Entry(root, bg='gray', bd=3)
ent.pack(fill=BOTH, side=BOTTOM)
ent.focus_set() # 绑定事件
root.bind("<Return>", lambda event:send(ent, queue, text)) # 设置窗口其他属性
root.title("多人聊天室 - 管理员")
root.configure(bg="white")
root.iconbitmap("python.ico") # 主循环函数
root.after(1000, recv, root, queueu, text) def recv(root, queueu, text):
if not queueu.empty():
data = queueu.get()
text.insert(END, data)
root.after(1000, recv, root, queueu, text) def send(ent, queue, text):
now = ":".join(ctime().split()[3].split(":"))
data = "[" + now + "] " + "管理员:" + ent.get() + "\n"
queue.put(data)
text.insert(END, data)
ent.delete(0, END) def inet(server, queue, queueu):
# 子进程
rlist = [server]
wlist = []
xlist = [] while True:
# 接收队列信息
if not queue.empty():
data = queue.get()
for conn in rlist:
if conn is not server:
conn.send(bytes(data, "UTF-8")) rs, ws, xs = select(rlist, wlist, xlist, 1) for r in rs:
if r is server:
conn, addr = r.accept()
rlist.append(conn)
else:
try:
data = r.recv(1024)
except:
rlist.remove(r)
else:
queueu.put(data.decode())
for conn in rlist:
if conn is not server:
conn.send(data) def main():
# 主进程
main_gui() if __name__ == "__main__":
main()
server.py
# client.py
# 客户端代码 import sys
from time import sleep, ctime
from multiprocessing import Process, Queue
from socket import *
from settings import *
from tkinter import *
from tkinter.scrolledtext import ScrolledText
from tkinter import messagebox def main_gui():
# 主窗口
root = Tk() # 设置窗口居中
center(root, 300, 200) # 设置窗口其他属性
root.title("多人聊天室主窗口")
root.resizable(0, 0)
root.configure(bg="white")
root.iconbitmap("python.ico") # 添加主机名(HOST)以及端口号(PORT)等输入框
pad = 10
Label(root, text="主机名(Host):").grid(row=0, column=0, padx=pad, pady=pad)
ent_host = Entry(root)
ent_host.insert(0, HOST)
ent_host.grid(row=0, column=1, padx=pad, pady=pad)
Label(root, text="端口号(Port):").grid(row=1, column=0, padx=pad, pady=pad)
ent_port = Entry(root)
ent_port.insert(0, PORT)
ent_port.grid(row=1, column=1, padx=pad, pady=pad)
Label(root, text="用户名(User):").grid(row=2, column=0, padx=pad, pady=pad)
ent_user = Entry(root)
ent_user.grid(row=2, column=1, padx=pad, pady=pad)
ent_user.focus_set() # 组件列表
widgets = {
"ent_host": ent_host,
"ent_port": ent_port,
"ent_user": ent_user
} # 添加确认按钮
btn_cfm = Button(root, text="加入目标聊天室", command=lambda:validate(root, widgets))
btn_cfm.grid(rowspan=2, columnspan=2, padx=pad, pady=pad) # 绑定事件
root.bind("<Return>", lambda event:validate(root, widgets)) # 主循环事件
root.mainloop() def validate(root, widgets):
# 确认按钮事件,检查是否输入有误
host, port, user = widgets["ent_host"].get(), widgets["ent_port"].get(), widgets["ent_user"].get() # 如果端口号不是纯数字
try:
port = int(port)
except:
messagebox.showerror("错误", "端口号必须为数字!")
return # 弹出错误窗口
if not host or not port or not user:
messagebox.showerror("错误", "主机名或端口或用户名不可为空!")
return # 有效地址
addr = (host, port) # 检查是否套接字成功
try:
client = socket(AF_INET, SOCK_STREAM)
client.connect(addr)
except Exception as e:
messagebox.showerror("错误", f"无法在{addr}上生成套接字!")
print(e)
return
else:
# 生成两个队列
# queue负责在子进程中循环get主进程的信息
# queueu负责在父进程中循环get子进程的消息
queue = Queue()
queueu = Queue() # 发送成功建立连接信息
client.send(bytes(f"{user}进入了聊天室。\n", "UTF-8")) # 生成子进程
process = Process(target=inet, args=(client, queue, queueu, user))
process.daemon = True
process.start() # 创建聊天室页面
chatroom_gui(root, queue, queueu, user) def chatroom_gui(r, queue, queueu, user):
# 聊天室页面
r.destroy()
root = Tk() # 设置窗口居中
center(root, 500, 500) # 最小化窗口
root.minsize(350, 350) # 菜单栏
menubar = Menu(root)
menubar.add_command(label="信息", command=None)
menubar.add_command(label="退出", command=root.destroy)
root.config(menu=menubar) # 文本框
text = ScrolledText(root)
text.pack(fill=BOTH) # 输入框
ent = Entry(root, bg='gray', bd=3)
ent.pack(fill=BOTH, side=BOTTOM)
ent.focus_set() # 绑定事件
root.bind("<Return>", lambda event:send(ent, queue, user)) # 设置窗口其他属性
root.title(f"多人聊天室 - {user}")
root.configure(bg="white")
# root.iconbitmap("python.ico") # 设置退出方法
root.protocol("WM_DELETE_WINDOW", lambda: exit(root, queue, user)) # 主循环函数
root.after(1000, recv, root, queueu, text) def exit(root, queue, user):
data = user + "退出了聊天室。\n"
queue.put(data)
sleep(1)
root.destroy()
sys.exit(0) def recv(root, queueu, text):
if not queueu.empty():
data = queueu.get()
if data == 404:
messagebox.showerror("错误", "服务端关闭了连接!")
sys.exit(0)
text.insert(END, data)
root.after(1000, recv, root, queueu, text) def send(ent, queue, user):
now = ":".join(ctime().split()[3].split(":"))
data = "[" + now + "] " + user + ":" + ent.get() + "\n"
queue.put(data)
ent.delete(0, END) def inet(client, queue, queueu, user):
# 子进程
client.setblocking(0)
while True:
if not queue.empty():
data = queue.get()
if data:
data = bytes(data, "UTF-8")
client.send(data)
try:
data = client.recv(1024)
except BlockingIOError as e:
continue
except:
queueu.put(404)
else:
data = data.decode()
queueu.put(data) def main():
# 主进程
main_gui() if __name__ == "__main__":
main()
client.py
运行截图:



Python实现网络图形化界面多人聊天室 - Windows的更多相关文章
- Python实现网络图形化界面多人聊天室 - Linux
网络图形化界面多人聊天室 - Linux Windows版本:https://www.cnblogs.com/noonjuan/p/12078524.html 在Python实现网络多人聊天室基础上, ...
- Python实现网络多人聊天室 - Windows
项目名称:多人聊天室项目结构: client.py server.py settings.py项目思路:服务端接收客户端连接,客户端发送信息给服务端,服务端将信息发送给所有客户端.项目实现:主进程负责 ...
- Python基于Socket实现简易多人聊天室
前言 套接字(Sockets)是双向通信信道的端点. 套接字可以在一个进程内,在同一机器上的进程之间,或者在不同主机的进程之间进行通信,主机可以是任何一台有连接互联网的机器. 套接字可以通过多种不同的 ...
- Python实现网络多人聊天室
网络多人聊天室 文件结构: chatroom ├── client.py # 客户端代码 ├── language.py # 语言文件 ├── server.py # 服务端代码 └── set ...
- java socket之多人聊天室Demo
一.功能介绍 该功能实现了一个类似QQ的最简单多人聊天室,如下图所示. 二.目录结构 三.服务端 1)SocketServer类,该类是服务端的主类,主要负责创建聊天窗口,创建监听客户端的线程: pa ...
- java小程序---简陋版多人聊天室
功能需求: 1 每运行一次主函数,创建一个客户端聊天界面; 2 客户端界面分三块,公屏(显示所有客户端发送的信息),私屏(用于输入个人想要发送的信息),发送按钮(点击一次,将客户端信息发送到服务端) ...
- Apache MiNa 实现多人聊天室
Apache MiNa 实现多人聊天室 开发环境: System:Windows JavaSDK:1.6 IDE:eclipse.MyEclipse 6.6 开发依赖库: Jdk1.4+.mina-c ...
- 与众不同 windows phone (31) - Communication(通信)之基于 Socket UDP 开发一个多人聊天室
原文:与众不同 windows phone (31) - Communication(通信)之基于 Socket UDP 开发一个多人聊天室 [索引页][源码下载] 与众不同 windows phon ...
- 与众不同 windows phone (30) - Communication(通信)之基于 Socket TCP 开发一个多人聊天室
原文:与众不同 windows phone (30) - Communication(通信)之基于 Socket TCP 开发一个多人聊天室 [索引页][源码下载] 与众不同 windows phon ...
随机推荐
- layUI学习第五日:layUI布局系列二
6.列偏移 列偏移可针对不同屏幕的标准进行设定,只会在桌面屏幕下有效,当低于桌面屏幕的规定的临界值,就会堆叠排列. <div class="layui-col-md4 layui-co ...
- Codeforces Round #603 (Div. 2) D. Secret Passwords 并查集
D. Secret Passwords One unknown hacker wants to get the admin's password of AtForces testing system, ...
- golang数据结构之稀疏数组
掌握知识: 数组的初始化和赋值 结构体的初始化和赋值 字符串和整型之间的转换以及其它的一些操作 类型断言 读取文件 写入文件 对稀疏数组进行压缩 package main import ( " ...
- springboot整合shiro进行权限管理
背景:springboot2.1,shiro1.4:由于目前的小项目没做登录,但是客户又需要加上权限,因此楼主就想到了shiro(这是单独的项目,需要集成后台管理系统) shiro简介 Apache ...
- CMake使用总结(一)
当我们在写CMakeLists.txt文件时,常常会搞不明白link_directories, LINK_LIBRARIES, target_link_libraries这3者的区别,下面就其详细介绍 ...
- 分享一下今天遇到的两个问题,一个是关于C语言内存泄漏问题,另一个是关于Linux下grep使用时的问题
C语言内存泄漏问题: 给出如下代码: #include <stdio.h> #include <stdlib.h> int main(){ int *p; p=(int*)ma ...
- spring的事件机制实战
理论 在分布式场景下,实现同步转异步的方式有三种方式: 1.异步线程池执行:比如借助@Asyn注解,放到spring自带的线程池中去执行: 2.放到消息队列中,在消费者的代码中异步的消费,执行相关的逻 ...
- 纯js的统计图插件-统计图
第一次写博客,写的不到望大家见谅! 今天给大家分享一个纯js的插件(统计图),有知道的可以在下面评论一起谈论一下,刚学着的时候,我是看了好久才看懂的一个基本结构,到后来我才知道原来直接去原网站上找到复 ...
- DesignPattern系列__08UML相关知识
前言 现在,很少有人和90年代一样,自己去实现一个软件的各个方面,也就是说,在工作中,和人沟通是必备的技能.那么,作为一枚码农,如何和他人沟通呢?这就要依靠本文的主题了--UML. 简介 UML--U ...
- HTML5新标签与特性---多媒体
多媒体标签 embed:标签定义嵌入的内容 audio:播放音频 video:播放视频 多媒体 embed(会使用) embed可以用来插入各种多媒体,格式可以是 Midi.Wav.AIFF.AU.M ...