参与拿奖:本文已参与「新人创作礼」活动,一起开启掘金创作之路
ps:代码文末自取
1.运行结果
主要实现功能有发送、接收消息,清空发送框内容,退出聊天
2.UI部分代码
主要包括三个输入框,五个按钮,以及一个列表框
root=tkinter.Tk() # 创建窗口
root.title(title) # 窗口名字
root['height']=500
root['width']=500
var_Message=tkinter.StringVar() # 信息
var_Message.set('')
var_Name=tkinter.StringVar()
var_Name.set(title)
var_Host=socket.gethostname() # 获取主机host
var_port=tkinter.StringVar() # 端口号
var_port.set(str(port))
label_h=tkinter.Label(root,text="Name:",width=60)
label_h.place(x=10,y=6,width=60,height=20)
entry_h=tkinter.Entry(root,textvariable=var_Name)
entry_h.place(x=80,y=6,width=240,height=20)
label_h=tkinter.Label(root,text="Port:",width=60)
label_h.place(x=10,y=30,width=60,height=20)
entry_h=tkinter.Entry(root,textvariable=var_port)
entry_h.place(x=80,y=30,width=240,height=20)
label_m=tkinter.Label(root,text="Message:",width=60)
label_m.place(x=10,y=60,width=60,height=20)
entry_m=tkinter.Entry(root,textvariable=var_Message)
entry_m.place(x=80,y=60,width=240,height=20)
listBox=tkinter.Listbox(root) # 列表框
listBox.place(x=80,y=200,width=240,height=200)
button_co=tkinter.Button(root,text="Connect",width=36,command=Connect) # 连接按钮
button_co.place(x=80,y=100,width=60,height=20)
button_d=tkinter.Button(root,text="Deliver",width=36,command=Deliver) # 发送按钮
button_d.place(x=200,y=100,width=60,height=20)
button_r=tkinter.Button(root,text="Receive",width=36,command=Receive) # 接受按钮
button_r.place(x=80,y=160,width=60,height=20)
button_cl=tkinter.Button(root,text="Clean",width=36,command=Clean) # 清空按钮
button_cl.place(x=200,y=160,width=60,height=20)
button_q=tkinter.Button(root,text="Quit",width=36,command=Quit) # 退出按钮
button_q.place(x=360,y=360,width=60,height=20)
root.mainloop()
3.功能部分
3.1 绑定host与端口
首先为了区分服务端与客户端,使用了if条件判断,如果是服务器端,需要绑定host和端口并创建监听;如果是客户端直接连接host与端口即可。
if title=="Server": # 服务端
s.bind((var_Host, port))
s.listen(5)
c, addr = s.accept()
else: # 客户端
s.connect((var_Host, port))
3.2 发送功能代码
def Deliver():
tag=True
global s
global r
if title=="Server": # 服务端
try:
data_s = entry_m.get()
c.send(data_s.encode('utf-8'))
listBox.insert(r,"A: "+data_s+"\n")
r+=1
except:
print("Server Deliver Error!")
else: # 客户端
try:
data_s = entry_m.get()
s.send(data_s.encode('utf-8'))
listBox.insert(r, "B: "+data_s + "\n")
r+=1
except:
print("Client Deliver Error!")
3.3 接收功能代码
def Receive():
global s
global r
if title=="Server":
try:
data = c.recv(1024).decode() # 接收消息,并解码
listBox.insert(r,"B: "+data+"\n")
r+=1
except:
print("Server Receive Error!")
else:
try:
data_re = s.recv(1024).decode()
listBox.insert(r, "A: " + data_re + "\n")
r+=1
except:
print("Client Receive Error!")
4.完整代码
import tkinter
import tkinter.messagebox
import tkinter.ttk
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
r=0
def window(title,port):
root=tkinter.Tk() # 创建窗口
root.title(title) # 窗口名字
root['height']=500
root['width']=500
var_Message=tkinter.StringVar() # 信息
var_Message.set('')
var_Name=tkinter.StringVar()
var_Name.set(title)
var_Host=socket.gethostname()
var_port=tkinter.StringVar()
var_port.set(str(port))
label_h=tkinter.Label(root,text="Name:",width=60)
label_h.place(x=10,y=6,width=60,height=20)
entry_h=tkinter.Entry(root,textvariable=var_Name)
entry_h.place(x=80,y=6,width=240,height=20)
label_h=tkinter.Label(root,text="Port:",width=60)
label_h.place(x=10,y=30,width=60,height=20)
entry_h=tkinter.Entry(root,textvariable=var_port)
entry_h.place(x=80,y=30,width=240,height=20)
label_m=tkinter.Label(root,text="Message:",width=60)
label_m.place(x=10,y=60,width=60,height=20)
entry_m=tkinter.Entry(root,textvariable=var_Message)
entry_m.place(x=80,y=60,width=240,height=20)
listBox=tkinter.Listbox(root)
listBox.place(x=80,y=200,width=240,height=200)
global s
def Connect():
pass
if title=="Server": # 服务端
s.bind((var_Host, port))
s.listen(5)
c, addr = s.accept()
else: # 客户端
s.connect((var_Host, port))
def Deliver():
tag=True
global s
global r
if title=="Server":
try:
data_s = entry_m.get()
c.send(data_s.encode('utf-8'))
listBox.insert(r,"A: "+data_s+"\n")
r+=1
except:
print("Server Deliver Error!")
else:
try:
data_s = entry_m.get()
s.send(data_s.encode('utf-8'))
listBox.insert(r, "B: "+data_s + "\n")
r+=1
except:
print("Client Deliver Error!")
def Receive():
global s
global r
if title=="Server":
try:
data = c.recv(1024).decode()
listBox.insert(r,"B: "+data+"\n")
r+=1
except:
print("Server Receive Error!")
else:
try:
data_re = s.recv(1024).decode()
listBox.insert(r, "A: " + data_re + "\n")
r+=1
except:
print("Client Receive Error!")
def Clean():
try:
var_Message.set('')
except:
print("Error!")
def Quit():
s.close()
root.destroy()
button_co=tkinter.Button(root,text="Connect",width=36,command=Connect) # 连接按钮
button_co.place(x=80,y=100,width=60,height=20)
button_d=tkinter.Button(root,text="Deliver",width=36,command=Deliver) # 发送按钮
button_d.place(x=200,y=100,width=60,height=20)
button_r=tkinter.Button(root,text="Receive",width=36,command=Receive) # 接受按钮
button_r.place(x=80,y=160,width=60,height=20)
button_cl=tkinter.Button(root,text="Clean",width=36,command=Clean) # 清空按钮
button_cl.place(x=200,y=160,width=60,height=20)
button_q=tkinter.Button(root,text="Quit",width=36,command=Quit) # 退出按钮
button_q.place(x=360,y=360,width=60,height=20)
root.mainloop()
def Server():
window('Server',1206)
def Client():
window('Client',1206)
if __name__ == '__main__':
Server()
# Client()
5.运行方式
先运行Server(),然后打开另外一个运行界面(这里使用的终端),运行Client()即可弹出聊天框。发送和接收是配对的,一般是先手动发送然后手动检查是否有未接收消息。