基于Python的Socket编程模拟初代QQ(自定义协议)Pycharm

2020-07-05

需求说明:

1,转发消息
2,处理登录
3,处理退出
4,维护历史消息,维护在线用户,维护在线用户的连接

详细细节:

1, 多线程去处理每个用户连接,防止主线程阻塞

2,自定义了消息协议,并且自己完成了消息协议的解析

代码:

客户端:

 1 import socket
 2 import json
 3 import threading
 4 
 5 client = socket.socket()
 6 client.connect(("10.211.55.31", 8000))
 7 
 8 user = "Penguin1"
 9 
10 # 1,登录
11 login_template = {
12     "action": "login",
13     "user": user
14 }
15 client.send(json.dumps(login_template).encode("utf8"))
16 res = client.recv(1024)
17 print(res.decode("utf8"))
18 
19 # 2,获取在线用户
20 get_user_template = {
21     "action": "list_user",
22 }
23 client.send(json.dumps(get_user_template).encode("utf8"))
24 res = client.recv(1024)
25 print("当前在线用户:{}".format(res.decode("utf8")))
26 
27 # 3,获取历史消息
28 offonline_msg_template = {
29     "action": "history_msg",
30     "user": user
31 }
32 client.send(json.dumps(offonline_msg_template).encode("utf8"))
33 res = client.recv(1024)
34 print("历史消息:{}".format(res.decode("utf8")))
35 
36 exit = False
37 
38 def handle_receive():
39     # 处理接受请求
40     while True:
41         if not exit:
42             try:
43                 res = client.recv(1024)
44             except:
45                 break
46             res = res.decode("utf8")
47             try:
48                 res_json = json.loads(res)
49                 msg = res_json["data"]
50                 from_user = res_json["from"]
51                 print("收到来自({})用户的消息:{}".format(from_user, msg))
52             except:
53                 print(res)
54         else:
55             break
56 
57 
58 def handle_send():
59     while True:
60         # 1,随时发送消息
61         # 2,有消息能够随时接收到
62         op_type = input("请输入你要进行的操作:1,发送消息 2,退出 3,获取当前在线用户")
63         if op_type not in ["1", "2", "3"]:
64             print("不支持该操作")
65             op_type = input("请输入你要进行的操作:1,发送消息 2,退出 3,获取当前在线用户")
66         elif op_type == "1":
67             to_user = input("请输入你要发送到用户")
68             msg = input("请输入你要发送到消息")
69             send_data_template = {
70                 "action": "send_msg",
71                 "to": to_user,
72                 "from": user,
73                 "date": msg,
74             }
75             client.send(json.dumps(send_data_template).encode("utf8"))
76         elif op_type == "2":
77             exit_template = {
78                 "actino": "exit",
79                 "user": user
80             }
81             client.send(json.dumps(exit_template).encode("utf8"))
82             exit = True
83             client.close()
84             break
85         elif op_type == "3":
86             get_user_template = {
87                 "action": "list_user"
88             }
89             client.send(json.dumps(get_user_template).encode("utf8"))
90 
91 
92 if __name__ == "__main__":
93     send_thread = threading.Thread(target=handle_send)
94     send_thread.start()
95     receive_thread = threading.Thread(target=handle_receive())
96     receive_thread.start()

服务器:

 1 import socket
 2 from collections import defaultdict
 3 import threading
 4 import json
 5 
 6 
 7 #1,维护用户连接
 8 online_users = defaultdict(dict)
 9 #注意一定是传的方法的名称
10 
11 # 2,维护用户的历史消息
12 user_msgs = defaultdict(list)
13 
14 server = socket.socket()
15 server.bind(("0.0.0.0", 8000))
16 server.listen()
17 
18 def handle_sock(sock, addr):
19     while True:
20         data = sock.recv(1024)
21         json_data = json.loads(data.decode("utf8"))
22         action = json_data.get("action", "")
23         if action == "login":
24             online_users[json_data["user"]] = sock
25             sock.send("登录成功".encode("utf8"))
26         elif action == "list_user":
27             #获取当前在线用户
28             all_users = [user for user, sock in online_users.items()]
29             sock.send(json.dumps(all_users).encode("utf8"))
30         elif action == "history_msg":
31             sock.send(json.dumps(user_msgs.get(json_data["user"], [])).encode("utf8"))
32         elif action == "send_msg":
33             if json_data["to"] in online_users:
34                 online_users[json_data["to"]].send(json.dumps(json_data).encode("utf8"))
35                 user_msgs[json_data["to"]].append(json_data)
36         elif action == "exit":
37             del online_users[json_data["user"]]
38             sock.send("退出成功!".encode("utf8"))
39 
40 while True:
41     #阻塞等待连接
42     sock,addr = server.accept()
43     #启动一个线程去处理新的用户连接
44     client_thread = threading.Thread(target = handle_sock,args = (sock,addr))
45     client_thread.start()
 
 
 
原文地址:https://www.cnblogs.com/liam-sliversucks/p/13251980.html