Python通过Socket实现QQ聊天功能

Python通过Socket实现QQ聊天功能@TOC

服务器端代码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")

  • 6
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值