使用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 "\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()