import tkinter as tk #导入窗体模块
import tkinter.filedialog #导入文件模块
import tkinter.messagebox #导入消息模块
import os #导入系统模块
from PIL import Image,ImageTk #导入图形模块 pip install pillow
import socket #导入通信模块
import threading #导入多线程模块
import time as timemodule #导入时间模块
import datetime #导入日期时间模块
import hashlib #文件名加密模块
import json #导入json模块
import struct #导入结构体模块
username = '' #用户名
password = '' #密码
serverAddr = None #连接地址
messageQueue = [] #消息列表
friendList = {} #通讯录列表
client = None #服务器连接对象
loginresult = '' #登陆返回值
Finduserresult = '' #查找用户返回结果
ip_port = ['gtol.f3322.org',9987] #默认服务器信息
serveropen = False #服务器连接标志
Fusername = '' #对话中的用户名
Fnickname = '' #对话中的用户名备注
#连接服务器
def serverlink(serverAddr):
global serveropen
global client
try:
# 定义socket类型,网络通信,UDP [socket.AF_INET 服务器之间网络通信] [socket.SOCK_DGRAM 数据报式socket , for UDP]
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(serverAddr) #连接服务器
jsThread = threading.Thread(target = jies, args=()) # TCL数据接收线程
jsThread.setDaemon(True)
jsThread.start()
serveropen = True
return True
except:
print('服务器连接失败!')
tk.messagebox.showwarning(title="警告", message="服务器连接失败!")
return False
#登陆类
class LoginWindow(tk.Tk):
''' 登录窗口 '''
#定义数据成员
serverIPEntry = None #服务器IP
serverPortEntry = None #服务器端口
usernameEntry = None #用户名
passwordEntry = None #密码
#初始化实例变量
def __init__(self):
tk.Tk.__init__(self) #实例化对象
self.serverIPEntry = tk.StringVar()
self.serverPortEntry = tk.StringVar()
self.usernameEntry = tk.StringVar()
self.passwordEntry = tk.StringVar()
self.title("IM(TCP) 登录") #窗体标题
self.setUI() #绘制登陆框
self.resizable(width=False, height=False) # 设置窗口宽高不可变.
width = 315 #设定窗口大小并居中在屏幕
height = 190
screenwidth = self.winfo_screenwidth() #获取屏幕尺寸以计算布局参数,使窗口居屏幕中央
screenheight = self.winfo_screenheight()
alignstr = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
self.geometry(alignstr) #窗体大小
self.mainloop() #显示窗体
#登陆界面
def setUI(self):
label1 = tk.Label(self, text = "服务器地址", font = ('Black', 13))
label1.place(x = 20, y = 10, width = 100, height = 25, anchor = tk.NW)
entry1 = tk.Entry(self, font = ('Black', 10), textvariable = self.serverIPEntry)
entry1.place(x = 130,y = 10, width = 150, height = 25, anchor =tk.NW)
self.serverIPEntry.set(ip_port[0])
label2 = tk.Label(self, text = "服务器端口", font = ('Black', 13))
label2.place(x = 20, y = 40, width = 100, height = 25, anchor = tk.NW)
entry2 = tk.Entry(self, font = ('Black', 10), textvariable = self.serverPortEntry)
entry2.place(x = 130,y = 40, width = 150, height = 25, anchor =tk.NW)
self.serverPortEntry.set(ip_port[1])
label3 = tk.Label(self, text = "用户名", font = ('Black', 13))
label3.place(x = 20, y = 70, width = 100, height = 25, anchor = tk.NW)
entry1 = tk.Entry(self, font = ('Black', 10), textvariable = self.usernameEntry)
entry1.place(x = 130,y = 70, width = 150, height = 25, anchor =tk.NW)
#self.usernameEntry.set('')
label4 = tk.Label(self, text = "密码", font = ('Black', 13))
label4.place(x = 20, y = 100, width = 100, height = 25, anchor = tk.NW)
entry1 = tk.Entry(self, font = ('Black', 10), textvariable = self.passwordEntry, show = "*")
entry1.place(x = 130,y = 100, width = 150, height = 25, anchor =tk.NW)
#self.passwordEntry.set('')
button1 = tk.Button(self, text = "默认服务器", font = ('Black', 12), command = self.defaultServer)
button1.place(x = 20, y = 140, width = 100, height = 35, anchor =tk.NW)
button2 = tk.Button(self, text = "登录", font = ('Black', 12), command = self.login)
button2.place(x = 160, y = 140, width = 50, height = 35, anchor =tk.NW)
button3 = tk.Button(self, text = "注册", font = ('Black', 12), command = self.register)
button3.place(x = 230, y = 140, width = 50, height = 35, anchor =tk.NW)
# 默认服务器信息
def defaultServer(self):
self.serverIPEntry.set(ip_port[0])
self.serverPortEntry.set(ip_port[1])
#登陆过程
def login(self):
global username
global password
global serverAddr
username = self.usernameEntry.get() #得到输入用户名
password = self.passwordEntry.get() #得到输入密码
#判断用户名和密码是否为空
if username == "" or password == "":
tk.messagebox.showwarning(title = "警告", message = "用户名与密码不能为空!")
return
#判断服务器IP和端口是否为空
if self.serverIPEntry.get() == "" or self.serverPortEntry.get() == "":
tk.messagebox.showwarning(title = "警告", message = "服务器地址与端口不能为空!")
return
#组合服务器连接信息
serverAddr = (self.serverIPEntry.get(), int(self.serverPortEntry.get()))
if not serveropen:
YN = serverlink(serverAddr) # 连接服务器
if not YN:
return
#组合登陆信息
user = str((username, None, password, "login"))
user = user.encode()#把接收和 bytes 转换成 str
print('发送登陆请求',user)
fas(user)#发送数据,请求登陆
global loginresult
while loginresult == '':
timemodule.sleep(1)
if loginresult == 'yes':
print ('登陆成功!')
self.destroy() # 销毁登陆窗口
else:
print('登陆失败!')
tk.messagebox.showwarning(title="警告", message="用户名或密码错误!")
loginresult = '' #清空登陆结果
#注册过程
def register(self):
global serverAddr
#如果服务器地址为空 或 端口为空
if self.serverIPEntry.get() == "" or self.serverPortEntry.get() == "":
tk.messagebox.showwarning(title = "警告", message = "服务器地址与端口不能为空!")
return
#获取服务器地址和端口
serverAddr = (self.serverIPEntry.get(), int(self.serverPortEntry.get()))
if not serveropen:serverlink(serverAddr) #连接服务器
username = self.usernameEntry.get() #获取用户名
password = self.passwordEntry.get() #获取密码
#检查用户名密码是否为空
if username == "" or password == "":
tk.messagebox.showwarning(title = "警告", message = "用户名与密码不能为空!")
return
#检查用户名和密码是否包�