python 一个命令行的聊天服务器

使用telnet连接
可以连接成功,但是客户端发送消息就会报类型不匹配的错
byte和str不匹配,这个错我实在找不到怎么改
如果有大佬知道,请告知我,谢谢!

解决了
collect_incoming_data传来的参数data是byte类型的,需要用decode转换

# 异步套接字
from asyncore import dispatcher
from asynchat import async_chat
import socket, asyncore

PORT = 5005
NAME = 'TestChar'

class EndSession(Exception):
    pass

class CommandHandler:
    def unknown(self, session, cmd):
        session.push('Unknown command:{}s\r\n'.format(cmd))

    def handle(self, session, line):
        if not line.strip(): return
        # 提取命令
        parts = line.split(' ', 1)
        cmd = parts[0]
        try: line = parts[1].strip()
        except IndexError: line=''
        # 尝试查找处理程序
        meth = getattr(self, 'do_'+cmd, None)
        try:
            meth(session, line)
        except TypeError:
            self.unknown(session, cmd)

class Room(CommandHandler):
    def __init__(self, server):
        self.server = server
        self.sessions = []

    def add(self, session):
        self.sessions.append(session)

    def remove(self, session):
        self.sessions.remove(session)

    def broadcast(self, line):
        '''将内容发送给聊天室内所有会话'''
        for session in self.sessions:
            session.push(line.encode())

    def do_logout(self, session, line):
        raise EndSession

class LoginRoom(Room):
    # 为刚连接的用户准备的聊天室
    def add(self, session):
        Room.add(self, session)
        # send hello
        self.broadcast('Welcome to {}\r\n'.format(self.server.name))

    def unknown(self, session, cmd):
        # 除login和logout外的所有命令都会导致系统显示
        session.push('Please log in\nUse "login <nick>"\r\n')

    def do_login(self, session, line):
        name = line.strip()
        if not name:
            session.push('Please enter a name\r\n')
        elif name in self.server.users:
            session.push('The name "{}" is taken.\r\n'.format(name))
            session.push('Please try again.\r\n')
        else:
            session.name = name
            session.enter(self.server.main_room)

class ChatRoom(Room):
    # 多人聊天室
    def add(self, session):
        # 告诉所有人新用户进入
        self.broadcast(session.name + 'has entered the room.\r\n')
        self.server.users[session.name] = session
        super().add(session)
    def remove(self, session):
        Room.remove(self,session)
        # 告诉所有人有用户离开
        self.broadcast(session.name + 'has left the room.\r\n')
    def do_say(self, session, line):
        self.broadcast(session.name+':'+line+'\r\n')
    def do_look(self, session, line):
        # 查看聊天室里都有谁
        session.push(session.name+'\r\n')
    def do_who(self, session, line):
        session.push('The following are logged in:\r\n')
        for name in self.sessions.users:
            session.push(name+'\r\n')

class LogoutRoom(Room):
    def add(self, session):
        try: del self.server.users[session.name]
        except KeyError: pass


class ChatSession(async_chat):
    def __init__(self, server, sock):
        super().__init__(sock)
        self.server = server
        self.set_terminator("\r\n")
        self.data=[]
        self.name = None
        # 所有会话最终都位于LoginRoom中
        self.enter(LoginRoom(server))

    def enter(self, room):
        # 从当前聊天室离开,进入下一个聊天室
        try: cur = self.room
        except AttributeError:pass
        else: cur.remove(self)
        self.room = room
        room.add(self)

    #
    def collect_incoming_data(self, data):
        self.data.append(data)

    def found_terminator(self):
        line = ''.join(self.data)
        self.data = []
        try: self.room.handle(self, line)
        except EndSession: self.handle_close()

    def handle_close(self):
        async_chat.handle_close(self)
        self.enter(LogoutRoom(self.server))

class ChatServer(dispatcher):
    def __init__(self, port, name):
        super().__init__()
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.set_reuse_addr() # 端口释放立刻被使用
        self.bind(('',port))
        self.listen(5)
        self.name = name
        self.users={}
        self.main_room = ChatRoom(self)

    def handle_accept(self):
        conn, addr = self.accept()
        ChatSession(self, conn)

if __name__ == '__main__':
    s = ChatServer(PORT, NAME)
    try: asyncore.loop()
    except KeyboardInterrupt: print()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值