import tkinter as tk import tkinter.messagebox import socket import datetime import os import threading import time

def analyze_and_build(raw): rawlist = raw.decode('utf-8').split('-$-') method = rawlist[0] if method == 'n': time = datetime.datetime.fromtimestamp(float(rawlist[1])).strftime('%Y-%m-%d %H:%M:%S') name = rawlist[2] content = rawlist[3] return '%s %s: %s

' % (time, name, content) elif method == 'e': time = datetime.datetime.fromtimestamp(float(rawlist[1])).strftime('%Y-%m-%d %H:%M:%S') name = rawlist[2] return '%s %s加入了聊天

' % (time, name) elif method == 'q': name = rawlist[1] return '%s退出了聊天

' % name elif method == 'f': # 文件传输 filename = rawlist[1] filesize = int(rawlist[2]) return f'收到来自 {name} 的文件: {filename} ({filesize} 字节)

'

def mainview(): name = nameEntry.get() host = hostEntry.get() port = portEntry.get() if name == '' or host == '' or port == '': tkinter.messagebox.showinfo(title='登录错误', message='参数不能为空!') else: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host, int(port))) loginWindow.destroy() mainWindow = tk.Tk() mainWindow.title('聊天室 - %s | %s:%s' % (name, host, port)) mainWindow.geometry('440x390')

    showText = tk.Text(mainWindow, height=20, width=60)
    emptyLabel = tk.Label(mainWindow, height=1)
    writeText = tk.Text(mainWindow, height=4, width=60)
    showText.tag_config('red', foreground='red')

    showText.pack()
    emptyLabel.pack()
    writeText.pack()

    s.send(('e-$-%s-$-%s' % (datetime.datetime.now().timestamp(), name)).encode('utf-8'))

    def fresh():
        while True:
            data = s.recv(1024)
            rawlist = data.decode('utf-8').split('-$-')
            if (rawlist[0] == 'n' or rawlist[0] == 'e') and rawlist[2] == name:
                showText.insert('end', analyze_and_build(data), 'black')
            else:
                showText.insert('end', analyze_and_build(data))
            if rawlist[0] == 'f':  # 文件传输
                # 接收文件
                filename = rawlist[1]
                filesize = int(rawlist[2])
                with open(filename, 'wb') as f:
                    received_size = 0
                    while received_size < filesize:
                        data = s.recv(1024)
                        f.write(data)
                        received_size += len(data)
                showText.insert('end', f'文件 {filename} 已成功保存!

') showText.see('end')

    t1 = threading.Thread(target=fresh)
    t1.start()

    def send_message():
        data = writeText.get('0.0', 'end')
        if data == '\n':
            pass
        else:
            s.send(('n-$-%s-$-%s-$-%s' % (datetime.datetime.now().timestamp(), name, data)).encode('utf-8'))
            writeText.delete('0.0', 'end')

    def send_file():
        # 选择要发送的文件
        filename = tk.filedialog.askopenfilename(initialdir='/', title='选择文件', filetypes=(('所有文件', '*.*'),))
        if filename:
            filesize = os.path.getsize(filename)
            # 发送文件信息
            s.send(f'f-$-{filename}-$-{filesize}'.encode('utf-8'))
            # 发送文件内容
            with open(filename, 'rb') as f:
                while True:
                    data = f.read(1024)
                    if not data:
                        break
                    s.send(data)
            showText.insert('end', f'文件 {filename} 已发送!

')

    sendButton = tk.Button(mainWindow, text='发送', width=5, height=1, command=send_message)
    sendFileButton = tk.Button(mainWindow, text='发送文件', width=8, height=1, command=send_file)
    sendButton.pack()
    sendFileButton.pack()

    def quit():
        s.send(('q-$-%s' % name).encode('utf-8'))
        time.sleep(0.5)
        s.send('_quitchatroom'.encode('utf-8'))
        mainWindow.destroy()
        os._exit(0)

    mainWindow.protocol('WM_DELETE_WINDOW', quit)
    mainWindow.mainloop()

loginWindow = tk.Tk() loginWindow.title('登录') loginWindow.geometry('200x250')

loginLabel = tk.Label(loginWindow, text='登录到聊天室', font=('Arial', 15), width=10, height=2)

nameLabel = tk.Label(loginWindow, text='您的昵称(xiaoming):', font=('Arial', 10), width=6, height=1)

hostLabel = tk.Label(loginWindow, text='主机(192.168.222.129):', font=('Arial', 10), width=6, height=1)

portLabel = tk.Label(loginWindow, text='端口(63342):', font=('Arial', 10), width=6, height=1)

nameEntry = tk.Entry(loginWindow) hostEntry = tk.Entry(loginWindow) portEntry = tk.Entry(loginWindow)

loginButton = tk.Button(loginWindow, text='登录', width=10, height=1, command=mainview)

loginLabel.pack() nameLabel.pack() nameEntry.pack() hostLabel.pack() hostEntry.pack() portLabel.pack() portEntry.pack() loginButton.pack()

loginWindow.mainloop()

Python 聊天室程序:实现文件传输功能

原文地址: https://www.cveoy.top/t/topic/nQlV 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录