二.整体思路
整体思路是用python的socket模块,与我的服务器进行连接,然后服务端把一个用户发送的内容再发送到每一个用户手上,就实现了群聊。
三.程序内容
该程序实现了
群聊
在线列表
登陆验证
等基本功能
接下来的版本会实现
数据传输加密
客户端哈希值验证
程序自毁功能
表情包发送
图片发送
已知问题
当注册不成功时,只能强制退出
待机久了会掉线(我是这样,别人没有遇到)
程序源码
客户端:
Mac版:
from tkinter import *
from tkinter.font import Font
# from tkinter.ttk import *
from tkinter import messagebox as mg
import time
import threading
import socket
def center_window(root, width, height):
"""
窗口居中代码
"""
screenwidth = root.winfo_screenwidth() # 获取显示屏宽度
screenheight = root.winfo_screenheight() # 获取显示屏高度
size = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2) # 设置窗口居中参数
root.geometry(size) # 让窗口居中显示
def fasong(*args):
time.sleep(0.1)
# re_data = input(">>")
re_data = send_entry.get("1.0", END)[:-1]
if 'exit' == re_data: # 判断是否退出
client.send(("Q "+ username).encode()) # 发送退出的请求
client.close()
elif (re_data != " \n" and re_data != "\n" and re_data != "" and re_data != " "): # 判断内容不为空
client.send(("C " + username + ": " + re_data).encode())
time_ = time.strftime('%Y-%m-%d %H:%M:%S') # 以下为自己说的话
chat_text.config(state=NORMAL)
f1 = Font(size=10)
chat_text.tag_config("tag_3", font=f1, foreground="grey")
chat_text.insert(END, time_, "tag_3") # 发送时间
chat_text.insert(END, "\n")
f = Font(size=15)
chat_text.tag_config("tag_41", font=f, foreground="#808080")
chat_text.insert(END, username + ":", "tag_41") # 发送文本内容
chat_text.insert(END, "\n")
f = Font(size=14)
chat_text.tag_config("tag_4", font=f, foreground="#2E8B57")
chat_text.insert(END, re_data, "tag_4") # 发送文本内容
chat_text.insert(END, "\n")
chat_text.config(state=DISABLED)
chat_text.see("end") # 转到最后一行
# send_entry.first()
# send_entry.delete(0.1,2.0) # 设置发送为空
# send_entry.insert('1 wordstart' , "s")
# time.sleep(0.1)
send_entry.delete("0.0", END) # 设置发送为空
def fa_(*args):
fasong()
# send_entry.delete("0.0", END) # 设置发送为空
return 'break'
def jieshou():
while True:
# time.sleep(0.3)
try:
data = client.recv(1024)
res = data.decode()
if(res != ''):
# print("1")
if (res.split(" ", 2)[0]=="C"): # 如果为聊天的请求
# print(res.split(" ", 1)[0])
# print(res.split(" ", 1)[1])
# print(res)
time_ = time.strftime('%Y-%m-%d %H:%M:%S')
chat_text.config(state=NORMAL)
f1 = Font(size=10)
chat_text.tag_config("tag_1", font=f1, foreground="grey")
chat_text.insert(END, time_, "tag_1")
chat_text.insert(END, "\n")
f = Font(size=15)
chat_text.tag_config("tag", font=f, foreground="#808080")
chat_text.insert(END, res.split(" ", 2)[1], "tag")
chat_text.insert(END, "\n")
f = Font(size=14)
chat_text.tag_config("tag_2", font=f)
chat_text.insert(END, res.split(" ", 2)[2], "tag_2")
chat_text.insert(END, "\n")
chat_text.config(state=DISABLED)
chat_text.see("end")
elif(res.split(" ", 1)[0]=="R"): # 在线用户请求
afd = False
print(res.split(" ", 1)[1])
for kk in range(0, online_user.size()): # 循环判断在线列表里是否有用户名
if online_user.get(kk) == (res.split(" ", 1)[1]): # 检测到是
afd = True # 判断变量为真
break # 退出
if (afd == False): # 如果判断变量为假
online_user.insert(END,res.split(" ", 1)[1]) # 插入用户名
elif(res.split(" ", 1)[0]=="E"): # 退出请求
for kk in range(0, online_user.size()): # 循环判断要删除的用户名
if online_user.get(kk) == (res.split(" ", 1)[1]):
online_user.delete(kk) # 从在线列表去除
break
# else:
# continue
except Exception as e:
print(e)
print("客户端已退出")
#break
def send():
"""
发送文字
"""
global username
username = username_string.get() # 用户名变量
# time.sleep(3)
if __name__ == "__main__":
# print("Welcome to Gouzi WD Chat")
# print(username)
#注册业务
while True:
# username=input("请输入用户名")
if ' ' not in username and username != " " and username != "": # 判断用户名不为空
client.send(("R "+username + " " + password_string.get()+"\n").encode()) # 发送注册请求
data=client.recv(2048).decode() # 最大接受字节
if data=="OK": # 如果穿回信息为 “OK”
break
else:
mg.showerror(""<