server.py
import socket
import json
import threading
HOST, PORT = '0.0.0.0', 8080
class Server():
def __init__(self, addr, port):
self.addr = addr
self.port = port
self.online = {}
self.server = socket.socket()
self.server.bind((self.addr, self.port))
self.server.listen()
self.accept()
def accept(self):
while True:
conn, addr = self.server.accept()
threading.Thread(target=self.receive, args=(conn,)).start()
def receive(self, conn):
while True:
try:
data = json.loads(conn.recv(1024).decode())
print('data:', data)
if data['online']:
if data['from'] not in self.online:
self.online[data['from']] = conn
print('self.online', self.online)
if data['to']:
print('to', data['to'], 'message', data['message'])
for user in data['to']:
self.send_message(self.online[user], data['message'], data['from'])
else:
for usr in self.online.keys():
self.send_message(self.online[usr], data['from']+'上线了\n', 'server')
self.send_message(conn, '欢迎上线,选择右侧用户进行交流\n', 'server')
except Exception as e:
print(data['from'], '下线了!!!')
self.online.pop(data['from'])
for usr in self.online.keys():
self.send_message(self.online[usr], '我下线了\n', data['from'])
break
def send_message(self, conn, message, _from):
print('conn', conn)
data = {}
data['from'] = _from
data['message'] = message
data['user_list'] = list(self.online.keys())
print('send_data', data)
conn.send(json.dumps(data).encode())
if __name__ == '__main__':
s = Server(HOST, PORT)
client.py
from tkinter import *
from tkinter.simpledialog import askstring
from tkinter.scrolledtext import ScrolledText
import json
import socket
import threading
import time
HOST, PORT = 'localhost', 8080
class Application(Frame):
def __init__(self, master, name, addr, port):
super(Application, self).__init__(master)
self.client = socket.socket()
self.client.connect((addr, port))
self.name = name
# self.name = askstring(title='用户名', prompt='请输入自己的姓名:')
self.show_text = ScrolledText(self, width=40, height=10, font=('华康少女字体', 20))
self.send_text = Text(self, width=40, height=5, font=('华康少女字体', 20))
self.send_button = Button(self, text='send', command=self.send_message, font=('华康少女字体', 20))
self.list_box = Listbox(self, selectmode=EXTENDED, height=10, width=10, font=('华康少女字体', 20))
self.grid()
self.create_widgets()
self.send_message()
def send_message(self, online=True):
data = {}
to = []
for i in self.list_box.curselection():
to.append(self.list_box.get(i))
message = self.send_text.get(0.0, END)
self.send_text.delete(0.0, END)
data['from'] = self.name
data['to'] = to
data['message'] = message
data['online'] = online
self.client.send(json.dumps(data).encode())
def create_widgets(self):
self.show_text.grid(row=0, column=0)
self.send_text.grid(row=1, column=0)
self.list_box.grid(row=0, column=1)
self.send_button.grid(row=1, column=1)
def recv_message(self):
while True:
data = self.client.recv(1024)
data = json.loads(data.decode())
message = data['message']
_from = data['from']
user_list = data['user_list']
self.show_text.insert(END, message)
self.show_text.insert(END, str(time.ctime())+' from:'+_from+'\n\n')
self.list_box.delete(0, END)
for item in user_list:
self.list_box.insert(END, item)
def __del__(self):
data = {}
data["online"] = False
data['from'] = self.name
self.client.send(json.dumps(data).encode())
if __name__ == '__main__':
root = Tk()
name = askstring(title='用户名', prompt='请输入自己的姓名:')
root.title(name)
app = Application(root, name, HOST, PORT)
# app.create_widgets()
t = threading.Thread(target=app.recv_message)
t.setDaemon(True)
t.start()
app.mainloop()