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 ...
随机推荐
- <DFS & BFS> 286 339 (BFS)364
286. Walls and Gates DFS: 思路是,搜索0的位置,每找到一个0,以其周围四个相邻点为起点,开始 DFS 遍历,并带入深度值1,如果遇到的值大于当前深度值,将位置值赋为当前深度值 ...
- Sharding-JDBC:垂直拆分怎么做?
经过读写分离的优化后,小王可算是轻松了一段时间,读写分离具体的方案请查看这篇文章: Sharding-JDBC:查询量大如何优化? 可是好景不长,业务发展是在太快了.数据库中的数据量猛增,由于所有表都 ...
- Expression #1 of ORDER BY clause is not in GROUP BY clause and contains nonaggregated column 'infor
今天在Navicat上执行SQL增删改查数据操作的时候出现了下面这个问题 Expression #1 of ORDER BY clause is not in GROUP BY clause and ...
- 【Linux命令】系统状态检测命令8个(ifconfig、uname、uptime、free、who、last、history、sosreport)
目录 ifconfig获取网卡配置信息 uname查看系统内核版本 uptime查看系统的负载信息 free查看内存信息 who查看当前主机用户的终端信息 last查看系统的登录记录 history查 ...
- 基于appium的常用元素定位方法
一.元素定位工具 app应用的元素使用的是控件定位,不同于web网页,web网页定位元素通常使用的是F12工具,那么在app当中我们则要借助其它的工具来辅助定位. 1.uiautomatorviewe ...
- linux检测远程端口是否打开
常用telnet ip port 方式(如telnet 172.17.193.18 5902)测试远程主机端口是否打开,或者用于测试当前环境与远程主机的端口之间的防火墙开通与否. telnet [ro ...
- Java设计模式:Builder(构建器)模式
概念定义 Builder模式是一步一步创建一个复杂对象的创建型模式.该模式将构建复杂对象的过程和它的部件解耦,使得构建过程和部件的表示隔离开来. 应用场景 对象创建过程比较复杂,或对创建顺序或组合有依 ...
- GNSS学习笔记--坐标转换
GNSS 坐标转换 GNSS计算主要涉及三个坐标系,地心地固坐标系,地理坐标系和站心坐标系.这里主要介绍一下三个坐标的含义和转换公式. 地心地固坐标系如图X,Y,Z表示 (ECEF坐标系),以地心O为 ...
- go语言使用go-sciter创建桌面应用(八) 窗口显示时,自动加载后端数据。
有些时候我们需要在窗口创建并显示时,加载一些后端的配置,这就需要用到view提供的几个事件. https://sciter.com/docs/content/sciter/View.htm state ...
- 基于 HTML5 WebGL 的 3D 科幻风机
前言 许多世纪以来,风力机同水力机械一样,作为动力源替代人力.畜力,对生产力的发展发挥过重要作用.近代机电动力的广泛应用以及二十世纪50年代中东油田的发现,使风机发电机的发展缓慢下来. 70年代初期, ...