Python程序设计之聊天小程序(TCP)

382 阅读3分钟
参与拿奖:本文已参与「新人创作礼」活动,一起开启掘金创作之路
ps:代码文末自取
1.运行结果

主要实现功能有发送、接收消息,清空发送框内容,退出聊天 屏幕截图(191).png

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()即可弹出聊天框。发送和接收是配对的,一般是先手动发送然后手动检查是否有未接收消息。