python写一个群聊的程序

需求分析:
聊天工具是CS程序,C是每一个客户端,S是服务端

服务应具有的功能:

  • 启动服务,包括绑定地址和端口,监听
  • 建立连接,能和多个客户端建立连接
  • 接收不同用户的信息
  • 分发,将接收的某个用户的信息转发到已连接的所有客户端
  • 停止服务
  • 记录连接的客户端
import logging
import socket
import threading

FORMAT = '%(asctime)s %(threadName)s %(message)s'
logging.basicConfig(format=FORMAT, level=logging.INFO)

class ChatServer:
    def __init__(self,ip='127.0.0.1',port=9999):
        self.sock = socket.socket()
        self.addr = (ip,port)
        self.event = threading.Event()
        self.clients = {}
        
    def start(self):
        self.sock.bind(self.addr)
        self.sock.listen()
        threading.Thread(target=self._accept,name='accept').start()
        
    def stop(self):
        for c in self.clients.values():
            c.close()
        self.sock.close()
        self.event.wait(3)
        self.event.set()
        
    def _accept(self):
        while not self.event.is_set():
            conn,client = self.sock.accept()
            self.clients[client] = conn
            threading.Thread(target=self._recv,args=(conn,client),name='recv').start()
            
    def _recv(self,conn,client):
        #接收到了数据,并分发
        while not self.event.is_set():
            try:
                data = conn.recv(1024)
            except Exception as e:
                logging.info('Error: {}'.format(e))
                data = b"quit"
            data = data.decode()
            logging.info(data)
            
            #客户端通知,退出机制
            if data == "quit":
                logging.info("-------quit-------")
                self.clients.pop(client)
                logging.info("conn close : {}".format(conn))
                conn.close()
                break
            
            msg = "ack {}".format(data)
            
            for conn in self.clients.values():
                conn.send(msg.encode())
            
if __name__=='__main__':            
    chat = ChatServer()
    chat.start()
    
    e = threading.Event()
    
    def showthreads():
        while not e.wait(5):
            logging.info(threading.enumerate())
    
    threading.Thread(target=showthreads, daemon=True).start()
    while not e.wait(1):
        cmd = input(">>> ").strip()
        if cmd == "quit":
            chat.stop()
            e.wait(3)
            break
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jepson2017

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值