#server
import socket
 import threading
 import json
 import select
 def send_data(client,addr):
     while(1):
         ss=input(f"要发送给{addr}输入:")
         client.send(ss.encode("utf-8"))
         pass
 def recv_data(client,addr,sockt_dict):
     threading.Thread(target=send_data,args=(client,addr,)).start()
     while(1):
         ###判断用户是否在线,如果recv抛出异常说明断线,那么给所有在线用户发送某某离线消息
         try:
             data=client.recv(1024)
         except Exception as e1:
             ss=json.loads(data.decode("utf-8"))
             cur_name=name
             for name in sockt_dict.keys():
                 if sockt_dict[name]==client:
                     cur_name=name
             del sockt_dict[cur_name]
             ###发送离线消息
             for name in sockt_dict:
                 msg={'type':'sysmessage','message':cur_name+'::已下线,当前用户列表如下\n'}
                 sockt_dict[name].send(json.dumps(msg).encode("utf-8"))
                 msg={'type':'sysmessage','message':str(list(sockt_dict.keys()))}
                 sockt_dict[name].send(json.dumps(msg).encode("utf-8"))
             client.close()
             break
        if not data:
             continue
         try:
             ss=json.loads(data.decode("utf-8"))
             if ss['type']=='text':
                 msg={'type':'text','message':ss['des_name']+"和你说::::》》"+ss['message']}
                 sockt_dict[ss['name']].send(json.dumps(msg).encode("utf-8"))
             elif ss['type']=='username':
                 sockt_dict[ss['name']]=client
                 print(sockt_dict)
                 for name in sockt_dict:
                     msg={'type':'sysmessage','message':str(list(sockt_dict.keys()))}
                     sockt_dict[name].send(json.dumps(msg).encode("utf-8"))
                 continue
             elif ss['type']=='userlist':
                 print("收到用户的消息")
                 msg={'type':'userlist','message':list(sockt_dict.keys())}
                 client.send(json.dumps(msg).encode("utf-8"))
                 continue
         except Exception as e2:
             print(e2)
             if ss['type']=='text':
                 try:
                     del sockt_dict[ss['name']]
                     msg={'type':'sysmessage','message':'发送消息失败,这个人已经下线!\n'}
                     sockt_dict[ss['des_name']].send(json.dumps(msg).encode("utf-8"))
                 except Exception as e:
                     msg={'type':'sysmessage','message':'发送消息失败,没有这个人!\n'}
                     sockt_dict[ss['des_name']].send(json.dumps(msg).encode("utf-8"))
                     pass
             pass
     
if __name__=="__main__":
     s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
     s.bind(("0.0.0.0",2000))
     s.listen(10)
     sockt_dict=dict()
     while(1):
         client,addr=s.accept()
         print(addr)
         threading.Thread(target=recv_data,args=(client,addr,sockt_dict,)).start()
         
 #client
import socket
 import threading
 import json
 people_list=[]
def send_data(client):
     global people_list
    ###发送用户名
     while(1):
         my_name=''
         tmp=dict()
         my_name=input("请输入姓名:")
         if my_name in people_list:
             print("用户名已存在,请使用其他用户名")
             continue
         tmp['type']="username"
         tmp['name']=my_name
         client.send(json.dumps(tmp).encode("utf-8"))
         break
    #接收消息
     while(1):
         tmp=dict()
         tmp['type']="text"
         tmp['des_name']=my_name
         tmp['name']=input("你想把消息发送给谁:")
         tmp['message']=input("请输入消息:")
         ss=json.dumps(tmp)+"\n"
         client.send(ss.encode("utf-8"))
if __name__=="__main__":
     s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
     s.connect(("127.0.0.1",2000))
     ###连接成功后发送获取所有用户列表消息,用于排除自己已存在的用户名
     tmp=dict()
     tmp['type']='userlist'
     s.send(json.dumps(tmp).encode("utf-8"))
     
     threading.Thread(target=send_data,args=(s,)).start()
     while(1):
         data=''
         try:
             data=s.recv(1024)
         except Exception as e:
             print("服务器断开")
             break
         if not data:
             continue
         ss=json.loads(data.decode("utf-8"))
        if ss['type']=='text':
             print("\n"+ss['message'])
         elif ss['type']=='userlist':
             people_list=ss['message']
             print("当前存在用户如下\n")
             print(people_list,"\n")
         elif ss['type']=='sysmessage':
             print("\n"+ss['message'])