服务端代码
import select, struct, socket, json
s = socket.socket()
s.bind(("192.168.14.190", 8848))
s.listen()
print("服务器开启")
r_list = [s,]
w_list = []
msg = []
dic = {}
while True:
readables, writeables, _ = select.select(r_list, w_list, [])
for c in readables:
if c == s:
new_c, addr = s.accept()
r_list.append(new_c)
else:
try:
length = struct.unpack("i", c.recv(4))[0]
data = json.loads(c.recv(length).decode("utf-8"))
print(data)
if data.get("name"):
dic[data.get("name")] = c
print("%s上线" % data.get("name"))
msg.append({"msg":"%s上线" % data.get("name"), "from":"server"})
w_list.append(c)
continue
msg.append(data)
w_list.append(c)
except ConnectionResetError:
dicname = None
for k,v in dic.items():
if v == c:
print("%s断开连接" % k)
msg.append({"msg":"%s下线" % k, "from":"server"})
r_list.remove(c)
w_list.append(c)
dicname = k
dic.pop(dicname)
for w in writeables:
for j in msg:
ip_addr = j.get("to_addr")
json_b = json.dumps(j).encode("utf-8")
length = struct.pack("i", len(json_b))
if ip_addr:
if dic.get(ip_addr):
dic[ip_addr].send(length)
dic[ip_addr].send(json_b)
else:
for i in r_list:
if i != s and i != w:
i.send(length)
i.send(json_b)
w_list.remove(w)
msg.pop()
客户端代码
import socket, json, struct
from threading import Thread
c = socket.socket()
c.connect(("192.168.14.190", 8848))
print("连接服务器成功")
def recver():
while True:
lens_bytes = c.recv(4)
lens = struct.unpack("i", lens_bytes)[0]
recv_msg = c.recv(lens).decode("utf-8")
json_data = json.loads(recv_msg)
print("来自%s:%s"%(json_data["from"],json_data["msg"]))
def send_info(info):
data = json.dumps(info).encode("utf-8")
c.send(struct.pack("i", len(data)))
c.send(data)
Thread(target=recver).start()
name = input("请输入昵称:").strip()
send_info({"name": name})
while True:
msg = input(">>:").strip()
if not msg:
continue
if "@" in msg:
info = {
"msg": msg.split("@")[0],
"to_addr": msg.split("@")[1],
"from": name
}
else:
info = {"msg": msg, "from": name}
send_info(info)