>  기사  >  백엔드 개발  >  파이썬 가상 티파티 효과

파이썬 가상 티파티 효과

php中世界最好的语言
php中世界最好的语言원래의
2018-04-09 11:58:371804검색

이번에는 파이썬 가상 티파티 효과에 대해 알려드리겠습니다. 파이썬 가상 티파티 효과에 대한 주의사항은 무엇인가요? 다음은 실제 사례입니다.

거의 모든 프로그래밍 언어를 배우고 사용할 때 소켓에 대한 연습이 결코 부족하지 않습니다. 특히 근거리 통신망 통신에 관해 글을 쓸 때는 더욱 그렇습니다. 그래서 책에 나오는 이 프로젝트는 소켓 프로그래밍을 연습하는데 딱 맞는 것 같아요.

이 연습의 전반적인 아이디어는 먼저 채팅 서버를 갖는 것입니다. 이 서버의 기능은 주로 클라이언트 소켓 연결을 제공하고, 각 클라이언트의 연결 세션을 저장하고, 각 연결에서 보낸 메시지를 처리하고, 클라이언트가 보낸 데이터. 클라이언트의 경우 코드를 작성할 필요가 없으며 시스템의 텔넷 도구를 사용하면 됩니다.

위의 분석을 보면 소켓을 캡슐화하는 두 클래스를 제외하고는 이 프로그램의 나머지 부분에 대해 말할 것이 별로 없다고 생각합니다.

이것을 파이썬에서 소켓 클래스를 이용해서 시도해보고, 간단한 통신 프로그램을 작성해 보았는데, 어째선지 통신 중에 항상 사고가 발생했습니다. 이 간단한 코드는 다음과 같습니다.

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이 소켓 통신 프로세스를 완료하기 위해 두 개의 캡슐화된 클래스를 제공하기 때문에 자세히 설명되지 않습니다. 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

전체 프로그램은 처음에 언급한 세 부분으로 나뉩니다:

클라이언트 소켓 연결 제공: ChatServer 클래스.

각 클라이언트의 연결 세션을 저장하고 각 연결에서 보낸 메시지를 처리합니다. ChatSession 클래스. 이 클래스의 기능은 매우 간단하며 데이터를 받아들이고 종결자가 있는지 확인합니다.

클라이언트가 보낸 데이터를 구문 분석합니다. 이는 나머지 방 관련 클래스입니다. 이 클래스는 클라이언트가 보낸 문자열 및 명령을 처리하는 데 사용되며 모두 CommandHandler에서 상속됩니다.

최종 스크린샷:

이 기사의 사례를 읽으신 후 방법을 마스터하셨다고 믿습니다. 더 흥미로운 정보를 보려면 PHP 중국어 웹사이트의 다른 관련 기사를 주목하세요!

추천 자료:

python2.7에서 pip를 사용할 수 없는 문제에 대한 완벽한 솔루션

Python 일괄 처리로 txt 파일을 DataFrame 형식으로 읽는 방법

위 내용은 파이썬 가상 티파티 효과의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.