Python通过Socket实现QQ聊天功能@TOC
来源:https://blog.csdn.net/huokundian/article/details/90668862
服务器端代码tcp_server_chat.py
#/usr/bin/python3 import socket import threading import chat if __name__ == '__main__': # 初始化socket server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 绑定IP地址和端口 server.bind(("localhost", 8888)) # 设置最大监听数 server.listen(5) # 设置一个字典,用来保存每一个客户端的连接 和 身份信息 socket_mapping = {} # 开启准备等待获取客户端的链接 while True: sc, addr = server.accept() # 为每一个客户端开启一个线程、保证程序的高效运行 threading.Thread(target=chat.server_chat, args=(sc, socket_mapping)).start()
客户端代码tcp_client_chat.py
#/usr/bin/python3 import socket import threading import chat class QQClient: """ QQ Client """ def __init__(self, qq): """ 初始化QQ号、并建立链接 :param qq: """ self.qq = qq # 创建 socket 客户端 self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 连接服务器 self.client.connect(("localhost", 8888)) # 发送自己的身份,给服务器 self.client.send(self.qq.encode()) def chat(self, to_qq): """ 和谁聊天 :param to_qq: :return: """ # 开启两个线程、分别进行接收(读取)数据、和发送(写入)数据 threading.Thread(target=chat.read_chat, args=(self.client,)).start() threading.Thread(target=chat.write_chat, args=(self.client, to_qq)).start()
chat.py
#/usr/bin/python3 def read_chat(socket): # 谁发送的、发送的内容 """ 读取别人发送过来的数据 :param socket: :return: """ while True: try: msg = socket.recv(1024).decode() # 将接收到的信息、打印到控制台上 print(msg) except ConnectionResetError: print("服务器连接失败、请重新连接~") break def write_chat(socket, to_qq): # 谁发的、发给谁的、内容 """ 发送信息给to_qq :param socket: :param to_qq: :return: """ while True: msg = input() # 准备发送给服务器的内容 msg = f"{to_qq}:{msg}" # 将信息发送给服务器 try: socket.send(msg.encode()) except ConnectionResetError: print("服务器连接失败、请重新连接~") break def server_chat(socket, socket_mapping): """ 服务器处理数据、并实现两个客户端的交互 :param socket: :param socket_mapping: :return: """ # 接收客户端的身份、并进行存储 qq = socket.recv(1024).decode() # 存储身份(这里也可以实现不允许同一账户多次登录) socket_mapping[qq] = socket # 给所有socket 显示 该用户上线了 for k, v in socket_mapping.items(): v.send(f"【{qq}】上线了".encode()) # 开启循环、用来不断的进行转发数据 while True: try: # 接收客户端发送的信息 data = socket.recv(1024).decode() to_qq, msg = data.split(":", 1) # 将信息转发给 to_qq 对应的客户端 to_socket = socket_mapping[to_qq] # 将信息发送给 to_socket to_socket.send(f"{qq}:{msg}".encode()) except ConnectionResetError: # 该客户端离线了 socket_mapping.pop(qq) # 提示所有的客户端、该用户下线了 for k, v in socket_mapping.items(): v.send(f"【{qq}】下线了".encode()) # 退出循环 break except KeyError: # 该用户不在线、提示fqq,您的好友不在线 socket.send(f"您的好友【{to_qq}】不在线".encode())
测试代码
// client1 #/usr/bin/python3 from tcp_client_chat import QQClient if __name__ == '__main__': # 登录QQ、并和服务器建立连接、模拟登录 qq = QQClient("13523456") # 开启聊天 qq.chat("472759903") // client2 from tcp_client_chat import QQClient if __name__ == '__main__': # 登录QQ、并和服务器建立连接、模拟登录 qq = QQClient("472759903") # 开启聊天 qq.chat("13523456")