1. Introduction
This project lesson is the server side and the client that implements the simple chat room Program.
2. Knowledge points
Server-side involves asyncore, asynchat and socket modules, The client uses the telnetlib, wx, time and thread these Modules.
second, the project actual combat (server Side) 1. Server class
First need a chat server, here inherit Asyncore dispatcher class to implement, the code is as follows
Class Chatserver (dispatcher): "" "" chat server "" " 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. Session Class
With the server class also need to be able to maintain each User's connection session, here inherit Asynchat Async_chat class to implement, the code is as Follows:
Class Chatsession (async_chat): "" " responsible and single user communication " "" def __init__ (self, server, sock): async_chat._ _init__ (self, sock) self.server = Server self.set_terminator (' \ n ') self.data = [] self.name = None Self.enter (loginroom (server)) def enter (self, rooms): ' remove itself from the current room and add to the specified room ' try: cur = Self.room except attributeerror: pass else: cur.remove (self) self.room = Guest Room.add (self) def collect_incoming_data (self, data): ' Accept Client-side ' self.data.append Found_terminator (self): ' When the end of a Client's data processing ' 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. Command interpreter
Now you need a command interpreter to interpret the User's commands, such as logging in, querying online users, sending messages, and so on, with the following code:
Class Commandhandler: "" "command handles" "" def unknown (self, session, cmd): ' response to unknown command ' Session.push (' Unknown command:%s\n '% cmd) def handle (self, session, line): ' command handling ' 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)
4. Room
Next we need to implement the room of the chat room, here we define three kinds of rooms, respectively, the user just log in the room, chat room and log out of the room, these three kinds of rooms have a common parent class, the code is as Follows:
Class Commandhandler: "" "contains Multiple User environments, responsible for basic command handling and broadcast" "" def __init__ (self, server): self.server = SE RVer self.sessions = [] def add (self, session): ' a user enters the room ' Self.sessions.append (session) def re Move (self, session): ' A user leaves the room ' self.sessions.remove (session) def broadcast (self, line): ' Send to all users Specify message ' for session ' in Self.sessions:session.push (line) def do_logout (self, session, line): ' exit Rooms ' Raise Endsessionclass loginroom (room): "" "the Room of the user just logged in" "" def add (self, session): ' user connection successful response ' Room.add (self, session) session.push (' Connect Success ') def do_login (self, session, line): ' Login command "name = Line.strip () if not name:session.push (' UserName Empty ') elif name in Self.serve R.users:session.push (' UserName Exist ') else:session.name = name Session.enter (se Lf.server.main_room) ClasS chatroom (room): "" "" "" "" "," "" "def add (self, session): ' broadcast new user enters ' Session.push (' Login Success ') Self.broadcast (session.name + ' has entered the room.\n ') self.server.users[session.name] = Session Room.add (self, session) def remove (self, session): ' broadcast user left ' Room.remove (self, Session) SELF.BROADC AST (session.name + ' have left the room.\n ') def do_say (self, session, line): ' client sends message ' Self.broadcast (ses Sion.name + ': ' + line + ' \ n ') def do_look (self, session, online): ' view on-site user ' Session.push (' web users:\n ' ) for others in Self.sessions:session.push (other.name + ' \ n ') class Logoutroom (room): "" "when the user exits "" "def Add (self, session): ' remove ' from server ' Try:del self.server.users[session.name] excep T Keyerror:pass
5. Server-side Complete code
Slightly
Small series Life also most hate this "slightly" word, but since you crossing already hard to see here, small make up not to point welfare is unkind.
Friendship Tip one: The skill of all the heroes, the first four kinds of code, you can call the Server-side complete code and small pieces of incense Kiss.
Friendship hint Two: The skill is insufficient the pro, please log in the laboratory building official Website: Http://www.shiyanlou.com/courses/?course_type=project&tag=all
, Retreat Practicing.
(hey, Don't throw eggs!) We are all civilized people! ?)
good -don't be Noisy ~ Advertising time is over, please crossing continue to watch !
third, the project actual combat (client)
After completing the server side, you need to implement the client, where the client connection server uses the Telnetlib module.
1. Login Window
Here the Graphics interface bread selected wxpython, the installation instructions, the login window by inheriting wx. The frame class is implemented with the following code:
Class Loginframe (wx. Frame): "" "login window" "" def __init__ (self, parent, id, title, size): ' initialize, add control and bind event ' Wx. frame.__init__ (self, parent, id, title) self. SetSize (size) self. Center () Self.serveraddresslabel = wx. Statictext (self, label = "Server Address", pos = (ten), size = (+)) Self.usernamelabel = wx. Statictext (self, label = "UserName", pos = (+, +), size = (+)) self.serveraddress = wx. Textctrl (self, pos = (+), size = (), Self.username = wx. Textctrl (self, pos = (), size = (), Self.loginbutton = wx. Button (self, label = ' Login ', pos = (+, 145), size = (+)) self.loginButton.Bind (wx. evt_button, Self.login) self. Show () def login (self, event): ' login processing ' try:serveraddress = Self.serverAddress.GetLineText (0). s Plit (': ') con.open (serveraddress[0], port = int (serveraddress[1]), Timeout = ten) response = Con.read _soMe () If response! = ' Connect Success ': self.showdialog (' Error ', ' connect fail! ', (95, 20)) return con.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 = (+)) except Exception: Self.showdialog (' error ', ' Connect fail! ', (+)) def showDialog (self, title, content, size): ' Display error message dialog box ' dialog = Wx. Dialog (self, title = title, size = Size) Dialog. Center () Wx. Statictext (dialog, label = Content) Dialog. ShowModal ()
2. Chat window
The main thing in the Chat window is to send a message to the server and accept the message from the server, which is accepted by the child thread, and the code is as Follows:
Class ChatFrame (wx. Frame): "" "chat window" "" def __init__ (self, parent, id, title, size): ' initialize, add control and bind event ' 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,.), size = (+)) Self.sendbutton = wx. Button (self, label = "Send", pos = (310, + =), size = (SELF.USERSBUTTON)) = Wx. Button (self, label = "Users", pos = (373, + =), size = (SELF.CLOSEBUTTON)) = Wx. Button (self, label = "Close", pos = (436, + =), size = (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): ' send messages ' message = str (self.message.Getlinetext (0)). Strip () If message! = ": con.write (' say ' + message + ' \ n ') self.message.Cle AR () def lookusers (self, event): ' view current online user ' Con.write (' look\n ') def close (self, event): ' Close window ' Con.write (' logout\n ') con.close () self. Close () def receive (self): ' message accepting server ' while true:sleep (0.6) result = Con.read_very _eager () If result! = ": Self.chatFrame.AppendText (result)
3. Client complete code
Cough Cough ~ Small series to tell you a sad news, (the public: go down!) All right, I think you should know That. client full code =1 (login window) +2 (chat Window) + self-adjustment, If you do not understand the spectators, please log in the laboratory building official Website: http://www.shiyanlou.com/courses/?course_type= Project&tag=all
I am wearing steel armor to drop, kiss, Gentle point ~)
Iv. Summary
finally, You can run the program to chat, note that you need to start the server and then start the Client. This project uses the Asyncore dispatcher to implement the server, Asynchat Asyn_chat to maintain the User's connection session, use Wxpython to implement the graphical interface, use Telnetlib to connect to the server, accept in the Sub-thread The message sent by the server is completed by a simple chat room Program.
The graphical interface here uses the wxpython, trying to change a graphics boundary bread to implement the Client. This program is very simple, you can also expand the function you Want.
Project effect
Login window
Chat window
Python chat Room