ホームページ >バックエンド開発 >Python チュートリアル >Python仮想ティーパーティー効果

Python仮想ティーパーティー効果

php中世界最好的语言
php中世界最好的语言オリジナル
2018-04-09 11:58:371869ブラウズ

今回は Python バーチャルお茶会の効果についてお届けします。 Python バーチャルお茶会の効果についての 注意事項 は次のとおりです。

ほぼすべての プログラミング言語 を学習して使用する場合、特にローカル エリア ネットワーク通信について記述する場合は、ソケットに関する練習が欠かせません。したがって、この本のプロジェクトはソケット プログラミングの練習に最適です。

この演習の全体的な考え方は、まずチャット サーバーを用意することです。このサーバーの機能は主に、クライアント ソケット接続を提供し、各クライアントの接続セッションを保存し、各接続によって送信されたメッセージを処理し、メッセージを解析することです。クライアントから送信されたデータ。クライアントに関しては、コードを記述する必要はなく、システムの Telnet ツールを使用するだけです。

上記の分析から、ソケットをカプセル化する 2 つのクラスを除いて、このプログラムの残りの部分については特に言うことはないと思います。

Pythonのソケットクラスを使って簡単な通信プログラムを書いてみましたが、なぜか通信中に必ず事故が発生してしまいました。この単純なコードは次のとおりです:

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()

このプログラムが失敗した理由は詳しく説明されていません。Python にはソケット通信プロセスを完了するために 2 つのカプセル化されたクラスが用意されているためです: asynchat async_chat と asyncore、および asyncore 自体で。前者のクラスはクライアントとサーバー間の各セッションを処理するために使用され、後者のクラスは主にソケット接続サービスを提供するために使用されます。そして、各ソケット接続は前者 (async_chat) によってホストされて処理されます。

コードを見てみましょう:

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

プログラム全体は、最初に述べた 3 つの部分に分かれています:

クライアントのソケット接続を提供します: ChatServer クラス。

各クライアントの接続セッションを保存し、各接続によって送信されたメッセージを処理します: ChatSession クラス このクラスの機能は非常に単純で、データを受け取り、ターミネーターがあるかどうかを判断し、ある場合は found_terminator メソッドを呼び出します。

クライアントから送信されたデータを解析します。これらは残りのルーム関連クラスであり、クライアントから送信された文字列とコマンドを処理するために使用され、それらはすべてCommandHandlerから継承されます。

最後のスクリーンショット:

この記事の事例を読んだ後は、この方法を習得したと思います。さらに興味深い情報については、php 中国語 Web サイトの他の関連記事に注目してください。

推奨読書:

Python2.7 で pip を使用できない問題に対する完璧な解決策

Python はどのようにして txt ファイルを DataFrame 形式にバッチで読み込むのか

以上がPython仮想ティーパーティー効果の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。