网站推广优化哪家正规,建筑公司企业愿景怎么写,白酒网站建设,小企业做网站多少钱项目实战#xff08;服务器端#xff09;
1.服务器类
首先需要一个聊天服务器#xff0c;这里继承asyncore的dispatcher类来实现#xff0c;代码如下
class ChatServer(dispatcher):聊天服务器def __init__(self, port):dispatcher…项目实战服务器端
1.服务器类
首先需要一个聊天服务器这里继承asyncore的dispatcher类来实现代码如下
class ChatServer(dispatcher):聊天服务器def __init__(self, port):dispatcher.__init__(self)self.create_socket(socket.AF_INET, socket.SOCK_STREAM)self.set_reuse_addr()self.bind((, port))self.listen(5)self.users {}self.main_room ChatRoom(self)def handle_accept(self):conn, addr self.accept()ChatSession(self, conn)
2.会话类
有了服务器类还需要能维护每个用户的连接会话这里继承asynchat的async_chat类来实现代码如下
class ChatSession(async_chat):负责和单用户通信def __init__(self, server, sock):async_chat.__init__(self, sock)self.server serverself.set_terminator(\n)self.data []self.name Noneself.enter(LoginRoom(server))def enter(self, room):从当前房间移除自身然后添加到指定房间try:cur self.roomexcept AttributeError:passelse:cur.remove(self)self.room roomroom.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))
3.命令解释器
现在就需要一个命令解释器能够解释用户的命令例如登录、查询在线用户和发消息等代码如下
class CommandHandler:命令处理类def unknown(self, session, cmd):响应未知命令session.push(Unknown command: %s\n % cmd)def handle(self, session, line):命令处理if not line.strip():returnparts 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)
4.房间
接下来就需要实现聊天室的房间了这里我们定义了三种房间分别是用户刚登录时的房间、聊天的房间和退出登录的房间这三种房间都有一个公共的父类代码如下
session.push(Login Success)self.broadcast(session.name has entered the room.\n)self.server.users[session.name] sessionRoom.add(self, session)def remove(self, session):广播用户离开Room.remove(self, session)self.broadcast(session.name has left the room.\n)def do_say(self, session, line):客户端发送消息self.broadcast(session.name : line \n)def do_look(self, session, line):查看在线用户session.push(Online Users:\n)for other in self.sessions:session.push(other.name \n)class LogoutRoom(Room):用户退出时的房间def add(self, session):从服务器中移除try:del self.server.users[session.name]except KeyError:pass
5.服务器端完整代码
#!/usr/bin/python
# encoding: utf-8from asyncore import dispatcher
from asynchat import async_chat
import socket, asyncorePORT 6666 #端口class EndSession(Exception):自定义会话结束时的异常passclass CommandHandler:命令处理类def unknown(self, session, cmd):响应未知命令session.push(Unknown command: %s\n % cmd)def handle(self, session, line):命令处理if not line.strip():returnparts 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 serverself.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)def do_logout(self, session, line):退出房间raise EndSessionclass LoginRoom(Room):刚登录的用户的房间def add(self, session):用户连接成功的回应Room.add(self, session)session.push(Connect Success)def do_login(self, session, line):登录命令处理name line.strip()if not name:session.push(UserName Empty)elif name in self.server.users:session.push(UserName Exist)else:session.name namesession.enter(self.server.main_room)class ChatRoom(Room):聊天用的房间def add(self, session):广播新用户进入session.push(Login Success)self.broadcast(session.name has entered the room.\n)self.server.users[session.name] sessionRoom.add(self, session)def remove(self, session):广播用户离开Room.remove(self, session)self.broadcast(session.name has left the room.\n)def do_say(self, session, line):客户端发送消息self.broadcast(session.name : line \n)def do_look(self, session, line):查看在线用户session.push(Online Users:\n)for other in self.sessions:session.push(other.name \n)class LogoutRoom(Room):用户退出时的房间def add(self, session):从服务器中移除try:del self.server.users[session.name]except KeyError:passclass ChatSession(async_chat):负责和单用户通信def __init__(self, server, sock):async_chat.__init__(self, sock)self.server serverself.set_terminator(\n)self.data []self.name Noneself.enter(LoginRoom(server))def enter(self, room):从当前房间移除自身然后添加到指定房间try:cur self.roomexcept AttributeError:passelse:cur.remove(self)self.room roomroom.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):dispatcher.__init__(self)self.create_socket(socket.AF_INET, socket.SOCK_STREAM)self.set_reuse_addr()self.bind((, port))self.listen(5)self.users {}self.main_room ChatRoom(self)def handle_accept(self):conn, addr self.accept()ChatSession(self, conn)if __name__ __main__:s ChatServer(PORT)try:asyncore.loop()except KeyboardInterrupt:print
三、项目实战客户端
完成了服务器端后就需要实现客户端了这里客户端连接服务器使用了telnetlib模块。 1.登录窗口
这里的图形界面包选择了wxPython前面有安装说明登录窗口通过继承wx.Frame类来实现代码如下
class LoginFrame(wx.Frame):登录窗口def __init__(self, parent, id, title, size):初始化添加控件并绑定事件wx.Frame.__init__(self, parent, id, title)self.SetSize(size)self.Center()self.serverAddressLabel wx.StaticText(self, label Server Address, pos (10, 50), size (120, 25))self.userNameLabel wx.StaticText(self, label UserName, pos (40, 100), size (120, 25))self.serverAddress wx.TextCtrl(self, pos (120, 47), size (150, 25))self.userName wx.TextCtrl(self, pos (120, 97), size (150, 25))self.loginButton wx.Button(self, label Login, pos (80, 145), size (130, 30))self.loginButton.Bind(wx.EVT_BUTTON, self.login)self.Show()def login(self, event):登录处理try:serverAddress self.serverAddress.GetLineText(0).split(:)con.open(serverAddress[0], port int(serverAddress[1]), timeout 10)response con.read_some()if response ! Connect Success:self.showDialog(Error, Connect Fail!, (95, 20))returncon.write(login str(self.userName.GetLineText(0)) \n)response con.read_some()if response UserName Empty:self.showDialog(Error, UserName Empty!, (135, 20))elif response UserName Exist:self.showDialog(Error, UserName Exist!, (135, 20))else:self.Close()ChatFrame(None, -2, title ShiYanLou Chat Client, size (500, 350))except Exception:self.showDialog(Error, Connect Fail!, (95, 20))def showDialog(self, title, content, size):显示错误信息对话框dialog wx.Dialog(self, title title, size size)dialog.Center()wx.StaticText(dialog, label content)dialog.ShowModal()
2.聊天窗口
聊天窗口中最主要的就是向服务器发消息并接受服务器的消息这里通过子线程来接受代码如下
class ChatFrame(wx.Frame):聊天窗口def __init__(self, parent, id, title, size):初始化添加控件并绑定事件wx.Frame.__init__(self, parent, id, title)self.SetSize(size)self.Center()self.chatFrame wx.TextCtrl(self, pos (5, 5), size (490, 310), style wx.TE_MULTILINE | wx.TE_READONLY)self.message wx.TextCtrl(self, pos (5, 320), size (300, 25))self.sendButton wx.Button(self, label Send, pos (310, 320), size (58, 25))self.usersButton wx.Button(self, label Users, pos (373, 320), size (58, 25))self.closeButton wx.Button(self, label Close, pos (436, 320), size (58, 25))self.sendButton.Bind(wx.EVT_BUTTON, self.send)self.usersButton.Bind(wx.EVT_BUTTON, self.lookUsers)self.closeButton.Bind(wx.EVT_BUTTON, self.close)thread.start_new_thread(self.receive, ())self.Show()def send(self, event):发送消息message str(self.message.GetLineText(0)).strip()if message ! :con.write(say message \n)self.message.Clear()def lookUsers(self, event):查看当前在线用户con.write(look\n)def close(self, event):关闭窗口con.write(logout\n)con.close()self.Close()def receive(self):接受服务器的消息while True:sleep(0.6)result con.read_very_eager()if result ! :self.chatFrame.AppendText(result)
3.客户端完整代码
#!/usr/bin/python
# encoding: utf-8import wx
import telnetlib
from time import sleep
import threadclass LoginFrame(wx.Frame):登录窗口def __init__(self, parent, id, title, size):初始化添加控件并绑定事件wx.Frame.__init__(self, parent, id, title)self.SetSize(size)self.Center()self.serverAddressLabel wx.StaticText(self, label Server Address, pos (10, 50), size (120, 25))self.userNameLabel wx.StaticText(self, label UserName, pos (40, 100), size (120, 25))self.serverAddress wx.TextCtrl(self, pos (120, 47), size (150, 25))self.userName wx.TextCtrl(self, pos (120, 97), size (150, 25))self.loginButton wx.Button(self, label Login, pos (80, 145), size (130, 30))self.loginButton.Bind(wx.EVT_BUTTON, self.login)self.Show()def login(self, event):登录处理try:serverAddress self.serverAddress.GetLineText(0).split(:)con.open(serverAddress[0], port int(serverAddress[1]), timeout 10)response con.read_some()if response ! Connect Success:self.showDialog(Error, Connect Fail!, (95, 20))returncon.write(login str(self.userName.GetLineText(0)) \n)response con.read_some()if response UserName Empty:self.showDialog(Error, UserName Empty!, (135, 20))elif response UserName Exist:self.showDialog(Error, UserName Exist!, (135, 20))else:self.Close()ChatFrame(None, -2, title ShiYanLou Chat Client, size (500, 350))except Exception:self.showDialog(Error, Connect Fail!, (95, 20))def showDialog(self, title, content, size):显示错误信息对话框dialog wx.Dialog(self, title title, size size)dialog.Center()wx.StaticText(dialog, label content)dialog.ShowModal()class ChatFrame(wx.Frame):聊天窗口def __init__(self, parent, id, title, size):初始化添加控件并绑定事件wx.Frame.__init__(self, parent, id, title)self.SetSize(size)self.Center()self.chatFrame wx.TextCtrl(self, pos (5, 5), size (490, 310), style wx.TE_MULTILINE | wx.TE_READONLY)self.message wx.TextCtrl(self, pos (5, 320), size (300, 25))self.sendButton wx.Button(self, label Send, pos (310, 320), size (58, 25))self.usersButton wx.Button(self, label Users, pos (373, 320), size (58, 25))self.closeButton wx.Button(self, label Close, pos (436, 320), size (58, 25))self.sendButton.Bind(wx.EVT_BUTTON, self.send)self.usersButton.Bind(wx.EVT_BUTTON, self.lookUsers)self.closeButton.Bind(wx.EVT_BUTTON, self.close)thread.start_new_thread(self.receive, ())self.Show()def send(self, event):发送消息message str(self.message.GetLineText(0)).strip()if message ! :con.write(say message \n)self.message.Clear()def lookUsers(self, event):查看当前在线用户con.write(look\n)def close(self, event):关闭窗口con.write(logout\n)con.close()self.Close()def receive(self):接受服务器的消息while True:sleep(0.6)result con.read_very_eager()if result ! :self.chatFrame.AppendText(result)程序运行
if __name__ __main__:app wx.App()con telnetlib.Telnet()LoginFrame(None, -1, title Login, size (280, 200))app.MainLoop()
四、小结
最后就可以运行程序进行聊天了注意需要先启动服务器再启动客户端。这个项目中使用了asyncore的dispatcher来实现服务器asynchat的asyn_chat来维护用户的连接会话用wxPython来实现图形界面用telnetlib来连接服务器在子线程中接受服务器发来的消息由此一个简单的聊天室程序就完成了。
更多资源见123云盘提取码AQGl https://www.123pan.com/s/f83gjv-nvWod