Python通過Socket實現QQ聊天功能


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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM