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")