Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import threading, socket, json, os
- from tkinter import *
- from tkinter import filedialog as fd
- from datetime import datetime
- SERVER_ADDR = '127.0.0.1', 1111 # Данные сервера
- class ChatClientWindow(Tk):
- def __init__(self, server_adr):
- super().__init__()
- self.server_adr = server_adr
- self._chat_sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
- self._chat_sock.connect(self.server_adr)
- self._initUI()
- rcv = threading.Thread(target=self._loop_recv)
- rcv.start()
- self.mainloop()
- def _initUI(self):
- self.title("Чат")
- self.geometry('600x400+200+100')
- # Name
- f_header = Frame(self)
- self.setName = Button(f_header, text="Установить имя", command=self._setNickname)
- self.setName.pack(side=RIGHT)
- self.nameStrVar = StringVar(value="")
- self.nameEntry = Entry(f_header, textvariable=self.nameStrVar, bd=0)
- self.nameEntry.pack(side=RIGHT, fill=BOTH, expand=True)
- f_header.pack(fill=X)
- # Messanges
- self.messText = Text(width=25, height=5, bg="darkgreen", fg='white', wrap=WORD)
- self.messText.pack(fill=BOTH, expand=True)
- # essage input field
- f_footer = Frame(self)
- self.sendFileButton = Button(f_footer, text="Отправить файл", command=self._sendFile)
- self.sendFileButton.pack(side=RIGHT)
- self.sendButton = Button(f_footer, text="Отправить", command=self._sendMess)
- self.sendButton.pack(side=RIGHT)
- self.messStrVar = StringVar(value="")
- self.messEntry = Entry(f_footer, textvariable=self.messStrVar, bd=0)
- self.messEntry.pack(side=RIGHT, fill=BOTH, expand=True)
- f_footer.pack(fill=X)
- def _setNickname(self):
- nickname = self.nameStrVar.get()
- if len(nickname) > 0 and len(nickname) < 32:
- self.nickname = nickname
- bmess = nickname.encode('utf-8')
- self._chat_sock.sendto(f'NICKNAME\r\nContent-Length:{len(bmess)}\r\n\r\n'.encode('utf-8') + bmess, self.server_adr)
- def _sendMess(self):
- messange = self.messStrVar.get()
- if len(messange) > 0:
- bmess = messange.encode('utf-8')
- self._chat_sock.send(f'MESSANGE\r\nContent-Length:{len(bmess)}\r\n\r\n'.encode('utf-8') + bmess)
- self.messStrVar.set("")
- def _sendFile(self):
- pathfile = fd.askopenfilename()
- with open(pathfile, 'rb') as f:
- filelen = os.fstat(f.fileno()).st_size
- filename = os.path.basename(pathfile)
- self._chat_sock.send(f'FILE\r\nContent-Length:{filelen}\nFile-name:{filename}\r\n\r\n'.encode('utf-8'))
- self._chat_sock.sendfile(f)
- def _loop_recv(self):
- request = b''
- while True:
- try:
- indexEndHead = request.find(b'\r\n\r\n')
- if indexEndHead != -1:
- head = request[:indexEndHead].splitlines()
- heads = {title[0]: title[1] for title in [line.split(b':', 1) for line in head[1:]]}
- if len(request[indexEndHead+4:]) >= int(heads[b'Content-Length']):
- data, request = request[indexEndHead+4:indexEndHead+4+int(heads[b'Content-Length'])], request[indexEndHead+4+int(heads[b'Content-Length']):]
- messjson = json.loads(data.decode('utf-8'))
- if messjson['type'] == 'mess':
- mess = f"[{datetime.fromtimestamp(messjson['date'])}] {messjson['name']}: {messjson['text']}\n"
- self.messText.insert(END, mess)
- elif messjson['type'] == 'system':
- mess = f"[{datetime.fromtimestamp(messjson['date'])}] {messjson['text']}\n"
- self.messText.insert(END, mess)
- elif messjson['type'] == 'file':
- with open(messjson['filename'], 'wb') as f:
- numBytes = 0
- while numBytes < int(messjson['len']):
- data = self._chat_sock.recv(1024)
- numBytes += len(data)
- f.write(data)
- mess = f"[{datetime.fromtimestamp(messjson['date'])}] received file {messjson['filename']} from {messjson['name']}\n"
- self.messText.insert(END, mess)
- self.messText.see(END)
- else:
- request += self._chat_sock.recv(1024)
- except:
- self._chat_sock.close()
- break
- def main():
- ChatClientWindow(SERVER_ADDR)
- if __name__ == '__main__':
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement