网络聊天程序的设计与实现 python实现 计算机网络课程设计

设计内容:

一、了解 Socket 通信的原理,在此基础上编写一个聊天程序。
二、在实现聊天功能的基础上,使用Tkinter实现聊天的界面

代码

server

from socket import *
import tkinter as tk
import tkinter.scrolledtext as tst
import time
import tkinter.messagebox
import threading


class Application(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        self.grid()
        self.createWidgets()

    def createWidgets(self):
        # 显示聊天窗口
        self.textEdit = tst.ScrolledText(self, width=50, height=15)
        self.textEdit.grid(row=0, column=0, rowspan=1, columnspan=4)
        # 定义标签,改变字体颜色
        self.textEdit.tag_config('server', foreground='red')
        self.textEdit.tag_config('guest', foreground='blue')

        # 编辑窗口
        self.inputText = tk.Text(self, width=40, height=5)
        self.inputText.grid(row=1, column=0, columnspan=1)
        # 定义快捷键,按下回车即可发送消息
        self.inputText.bind("", self.textSendReturn)
        # 发送按钮
        self.btnSend = tk.Button(self, text='send', command=self.textSend)
        self.btnSend.grid(row=1, column=3)
        # 开启一个线程用于接收消息并显示在聊天窗口
        t = threading.Thread(target=self.getInfo)
        t.start()

    def textSend(self):
        # 获取Text的所有内容
        str = self.inputText.get('1.0', 'end-1c')
        if str != "":
            # 显示发送时间和发送消息
            timemsg = '服务端' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\n'
            self.textEdit.config(state='normal')
            self.textEdit.insert(tk.END, timemsg, 'server')
            self.textEdit.insert(tk.END, str + '\n')
            # 将滚动条拉到最后显示最新消息
            self.textEdit.see(tk.END)
            self.textEdit.config(state='disabled')
            self.inputText.delete(0.0, tk.END)  # 删除输入框的内容
            # 发送数据到服务端
            sendMessage = bytes(str, encoding='utf8')
            # 发送输入的数据,与UDP有点不同,使用的是send方法,不需要指定服务器和端口,因为已经建立了一条tcp连接
            connectionSocket.send(sendMessage)
        else:
            tk.messagebox.showinfo('警告', "不能发送空白信息!")

    def getInfo(self):
        while True:
            recMsg = connectionSocket.recv(1024).decode("utf-8") + '\n'
            revTime = '客户端' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\n'
            # 通过设置state属性设置textEdit可编辑
            self.textEdit.config(state='normal')
            self.textEdit.insert(tk.END, revTime, 'guest')
            self.textEdit.insert(tk.END, recMsg)
            # 将滚动条拉到最后显示最新消息
            self.textEdit.see(tk.END)
            # 通过设置state属性设置textEdit不可编辑
            self.textEdit.config(state='disabled')

    def textSendReturn(self, event):
        if event.keysym == "Return":
            self.textSend()


root = tk.Tk()
root.title('服务端')

# 网络相关
# 指定服务器使用的端口
serverPort = 10000
serverSocket = socket(AF_INET, SOCK_STREAM)
# 绑定端口
serverSocket.bind(('127.0.0.1', serverPort))
# 定义最大连接数
serverSocket.listen(5)
print('等待连接....')
# 接受请求则建立一个连接
connectionSocket, addr = serverSocket.accept()
print('一个连接')
app = Application(master=root)
app.mainloop()

client

from socket import *
import tkinter as tk
import tkinter.scrolledtext as tst
import time
import tkinter.messagebox
import threading

class Application(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        self.grid()
        self.createWidgets()

    def createWidgets(self):
        # 显示聊天窗口
        self.textEdit = tst.ScrolledText(self, width=50, height=15)
        self.textEdit.grid(row=0, column=0, rowspan=1, columnspan=4)
        self.textEdit.config(state='disabled')
        # 定义标签,改变字体颜色
        self.textEdit.tag_config('server', foreground='red')
        self.textEdit.tag_config('guest', foreground='blue')

        # 编辑窗口
        self.inputText = tk.Text(self, width=40, height=5)
        self.inputText.grid(row=1, column=0, columnspan=1)
        # 定义快捷键,按下回车即可发送消息
        self.inputText.bind("", self.textSendReturn)

        # 发送按钮
        self.btnSend = tk.Button(self, text='send', command=self.textSend)
        self.btnSend.grid(row=1, column=3)

        # 开启一个线程用于接收消息并显示在聊天窗口
        t = threading.Thread(target=self.getInfo)
        t.start()

    def textSend(self):
        # 获取Text的所有内容
        # https://stackoverflow.com/questions/14824163/how-to-get-the-input-from-the-tkinter-text-box-widget
        str = self.inputText.get('1.0', 'end-1c')
        if str != "" and str != None:
            # 显示发送时间和发送消息
            timemsg = '客户端' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\n'
            # 通过设置state属性设置textEdit可编辑
            self.textEdit.config(state='normal')

            self.textEdit.insert(tk.INSERT, timemsg, 'guest')
            self.textEdit.insert(tk.INSERT, str + '\n')

            # 将滚动条拉到最后显示最新消息
            self.textEdit.see(tk.END)
            # 通过设置state属性设置textEdit不可编辑
            self.textEdit.config(state='disabled')
            self.inputText.delete(0.0, tk.END)  # 删除输入框的内容
            # 发送数据到服务端
            sendMessage = bytes(str, encoding='utf8')
            # 发送输入的数据,与UDP有点不同,使用的是send方法,不需要指定服务器和端口,因为已经建立了一条tcp连接
            clientSocket.send(sendMessage)
        else:
            tk.messagebox.showinfo('警告', "不能发送空白信息!")
    
    def getInfo(self):
        global clientSocket
        while True:
            # 接收数据,1024指定缓存长度,使用的是recv方法
            recMessage = clientSocket.recv(1024).decode("utf8") + '\n'
            # 接受时间和接收的数据
            recTime = '服务端' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\n'
            self.textEdit.config(state='normal')
            # server作为标签,改变字体颜色
            self.textEdit.insert(tk.END, recTime, 'server')
            self.textEdit.insert(tk.END, recMessage)
            # 将滚动条拉到最后显示最新消息
            self.textEdit.see(tk.END)
            self.textEdit.config(state='disabled')

    def textSendReturn(self, event):
        if event.keysym == "Return":
            self.textSend()


# 指定服务器地址,端口
servername = '127.0.0.1'
serverport = 10000
# ipRootFrame = tk.Tk()
# ipRootFrame.title('输入服务器ip')
# ipDialog = inputIPdialog(ipRootFrame)
# ipDialog.mainloop()
# socket第一个参数指定使用IPV4协议,第二个参数指定这是一个TCP套接字
clientSocket = None

try:
    clientSocket = socket(AF_INET, SOCK_STREAM)
except:
    tk.messagebox.showinfo('未知错误', '检查服务器地址是否错误!')

# tcp连接需要先经过握手建立连接
clientSocket.connect((servername, serverport))
root = tk.Tk()
root.title('客户端')

app = Application(master=root)
app.mainloop()

你可能感兴趣的:(python,计算机网络,python)