Dieser Artikel stellt hauptsächlich die virtuelle Teeparty des Python-Basis-Tutorialprojekts 5 im Detail vor. Es hat einen gewissen Referenzwert.
Fast jede Art von Programmiersprache lernen und verwenden An Socket-Übungen mangelt es nie, insbesondere wenn es um die Kommunikation in lokalen Netzwerken geht. Daher ist dieses Projekt im Buch genau das Richtige, um die Socket-Programmierung zu üben.
Die Gesamtidee dieser Übung besteht darin, zunächst einen Chat-Server zu haben. Die Hauptfunktionen dieses Servers bestehen darin, Client-Socket-Verbindungen bereitzustellen, die Verbindungssitzung jedes Clients zu speichern und die von jeder Verbindung gesendeten Nachrichten zu verarbeiten , und analysieren Sie die vom Client gesendeten Daten. Das ist alles. Für den Client müssen Sie keinen Code schreiben, sondern einfach das Telnet-Tool des Systems verwenden.
Ich denke, mit der obigen Analyse gibt es nicht viel über den Rest dieses Programms zu sagen, außer natürlich den beiden Klassen, die Sockets kapseln.
Ich habe dies mithilfe der Socket-Klasse in Python versucht und ein einfaches Kommunikationsprogramm geschrieben. Aus irgendeinem Grund kam es jedoch immer zu Unfällen bei der Kommunikation. Dieser einfache Code lautet wie folgt:
server.py
import socket mysocket = socket.socket(socket.AF_INET,socket.SOCK_STREAM) mysocket.bind(('',8888)) mysocket.listen(5) while True: connection,addr = mysocket.accept() revStr = connection.recv(1024) connection.send('Server:' + revStr) connection.close()
clinet.py
import socket import time clientsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) clientsocket.connect(('',8888)) while True: time.sleep(2) clientsocket.send('hello the5fire') print clientsocket.recv(1024) clientsocket.close()
Der Grund, warum dieses Programm fehlgeschlagen ist, wird nicht im Detail erklärt, da Python zwei gekapselte Klassen bereitstellt, um den Socket-Kommunikationsprozess abzuschließen: async_chat in Asynchat und Dispatcher in Asyncore Sowie Asyncore selbst. Die erstere Klasse wird verwendet, um jede Sitzung zwischen dem Client und dem Server abzuwickeln, und die letztere Klasse wird hauptsächlich zur Bereitstellung von Socket-Verbindungsdiensten verwendet. Und jede Socket-Verbindung wird von ersterem (async_chat) zur Verarbeitung gehostet.
Schauen wir uns den Code an:
from asyncore import dispatcher from asynchat import async_chat import socket, asyncore PORT = 5005 NAME = 'TestChat' class EndSession(Exception):pass class CommandHandler: def unknown(self, session, cmd): session.push('Unknown command: %s\r\n' % 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) def do_logout(self, session, line): raise EndSession class LoginRoom(Room): def add(self,session): Room.add(self,session) self.broadcast('Welcome to %s\r\n' % self.server.name) def unknown(self, session, cmd): 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 "%s" is taken.\r\n' % name) sessoin.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 Room.add(self, 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('The following are in this room:\r\n') for other in self.sessions: session.push(other.name + '\r\n') def do_who(self, session, line): session.push('The following are logged in:\r\n') for name in self.server.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): async_chat.__init__(self,sock) self.server = server self.set_terminator('\r\n') self.data = [] self.name = None 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): dispatcher.__init__(self) self.create_socket(socket.AF_INET, socket.SOCK_STREAM) 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
Das gesamte Programm ist in drei Teile gegliedert Wie ich am Anfang erwähnt habe. Jeder Teil:
Stellt die Socket-Verbindung des Clients bereit: ChatServer-Klasse.
Speichern Sie die Verbindungssitzung jedes Clients und verarbeiten Sie die von jeder Verbindung gesendeten Nachrichten: Die Funktion dieser Klasse ist sehr einfach. Sie akzeptiert Daten und ermittelt, ob ein Terminator vorhanden ist , wird die Methode „found_terminator“ aufgerufen.
Analysieren Sie die vom Client gesendeten Daten: Es handelt sich um die verbleibenden raumbezogenen Klassen. Diese Klassen werden zum Verarbeiten von vom Client gesendeten Zeichenfolgen und Befehlen verwendet und werden alle von CommandHandler geerbt.
Letzter Screenshot:
Verwandte Empfehlungen:
Python Basic Tutorial Project Three-in- ein XML
Python Basic Tutorial Project 2 Gute Bilder
Python Basic Tutorial Project 4 News Aggregation
Das obige ist der detaillierte Inhalt vonPython Basic Tutorial Projekt fünf virtuelle Teeparty. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!