Twisted는 모든 가능한 방식으로 좋습니다. 이식성이 뛰어나고 기능이 풍부하며 간단하고 확장 성이 뛰어나며 유지 관리가 잘되고 문서화가 잘되며 맛있는 오믈렛을 만들 수 있습니다. Asyncore는 모든 의도와 목적으로 폐기되었습니다.
그것은 트위스트 (나는 짧은 예에서 http/dns/ssh/smtp/pop/imap/irc/xmpp/process-spawning/multi-threading 서버를 보여 수있는 방법?) 짧은 대답에 우수한있는 모든 방법을 설명하기 어렵다, 그래서 대신 내가 사람들이 Twisted에 관해 가지고있는 것 같은 가장 일반적인 오해 중 하나에 초점을 맞 춥니 다 : asyncore보다 사용하기가 다소 복잡하거나 어렵습니다.
먼저 asyncore 예제부터 살펴 보겠습니다. 편향된 프리젠 테이션을 피하기 위해, 나는 여전히 asyncore를 조금 좋아하는 다른 누군가의 예를 사용할 것이다. 다음은 단순한 비동기식 예제 인 taken from Richard Jones' weblog입니다 (간략하게 설명을 생략 함).
먼저, 여기에 서버 :
import asyncore, socket
class Server(asyncore.dispatcher):
def __init__(self, host, port):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.bind(('', port))
self.listen(1)
def handle_accept(self):
socket, address = self.accept()
print 'Connection by', address
EchoHandler(socket)
class EchoHandler(asyncore.dispatcher_with_send):
def handle_read(self):
self.out_buffer = self.recv(1024)
if not self.out_buffer:
self.close()
s = Server('', 5007)
asyncore.loop()
여기에 클라이언트 :
import asyncore, socket
class Client(asyncore.dispatcher_with_send):
def __init__(self, host, port, message):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.connect((host, port))
self.out_buffer = message
def handle_close(self):
self.close()
def handle_read(self):
print 'Received', self.recv(1024)
self.close()
c = Client('', 5007, 'Hello, world')
asyncore.loop()
가이 코드가 제대로 처리하지 않는 몇 가지 모호한 경우가 있지만이를 설명하는 것은 지루 및 복잡하고 코드는 이미이 답변을 충분히 길게 만들었습니다.
다음은 Twisted와 기본적으로 동일한 코드입니다. 첫째, 서버 : 지금
from twisted.internet import reactor, protocol as p
class Echo(p.Protocol):
def dataReceived(self, data):
self.transport.write(data)
class EchoFactory(p.Factory):
def buildProtocol(self, addr):
print 'Connection by', addr
return Echo()
reactor.listenTCP(5007, EchoFactory())
reactor.run()
그리고, 클라이언트 :
내가 당신의 관심을 끌기 위해 싶은 몇 가지가 있습니다
from twisted.internet import reactor, protocol as p
class EchoClient(p.Protocol):
def connectionMade(self):
self.transport.write(self.factory.data)
def dataReceived(self, data):
print 'Received:', data
self.transport.loseConnection()
class EchoClientFactory(p.ClientFactory):
protocol = EchoClient
def __init__(self, data):
self.data = data
reactor.connectTCP('localhost', 5007, EchoClientFactory('Hello, world'))
reactor.run()
. 무엇보다 Twisted 예제는 25 % 더 짧습니다. asyncore는 40 줄, Twisted는 30 줄. 프로토콜이 점점 더 복잡 해짐에 따라 Twisted가 제공 할 수있는 asyncore에 대한 지원 코드를 더 많이 작성해야하므로이 차이가 더 커질 것입니다.
두 번째로, Twisted는 완전한 추상화을 제공합니다. asyncore 예제를 사용하면 socket
모듈을 사용하여 실제 네트워킹을 수행해야합니다. asyncore는 멀티플렉싱만을 제공합니다. portable behavior on platforms such as Windows이 필요하면 문제가됩니다. 또한 asyncore는 다른 플랫폼에서 비동기 서브 프로세스 통신을 수행 할 수있는 기능이 완전히 부족하다는 것을 의미합니다. 임의의 파일 설명자를 Windows의 select()
호출에 넣을 수 없습니다.
셋째, Twisted 예는 중성체입니다. Echo
및 EchoFactory
및 EchoClient
및 EchoClientFactory
은 TCP와 관련이 없습니다. 이 클래스들을 SSH, SSL, UNIX 소켓 또는 파이프를 통해 연결할 수있는 라이브러리로 만들려면 connectTCP
/listenTCP
콜을 하단에서만 변경하십시오. 프로토콜 논리에서 TLS와 같은 것을 지원하는 것은 매우 까다 롭습니다. 예를 들어, TLS의 '쓰기'는 하위 수준에서 '읽기'를 트리거합니다. 따라서 이러한 우려를 해결하기 위해서는 이러한 우려를 분리해야합니다.
마지막으로 MAC 주소와 이더넷 프레임을 직접 처리 할 경우 Twisted는 IP 및 이더넷 수준 네트워킹을 처리하기위한 저수준 라이브러리 인 Twisted Pair을 포함합니다. Twisted에서 가장 적극적으로 유지 관리되는 부분은 아닙니다. 코드가 꽤 오래되었습니다. 그러나 제대로 작동해야하며 그렇지 않은 경우 심각하게 버그를 발견하고 (결국) 고칠 수 있음을 확인합니다. 필자가 알고있는 한, asyncore에 필적할만한 라이브러리는 없으며 그러한 코드 자체는 포함되어 있지 않습니다.
왜 -1일까요? ... –
asyncore/asynchat는 소켓 처리에 직접 연결될 때만 유용합니다.내 코드에서,'스니퍼 (sniffer) '는 모든 소켓 항목을 처리하고 결과를 산출합니다. asyncore가 수행하기를 원하는 것은 내 첫 번째 및 두 번째 함수를 실행하고 '스니퍼'가 데이터를 반환 할 때 콜백을 발행 할 수있게하려는 것입니다. 어떻게하면 좋을까요? (나는 downvote하지 않았다, btw) – dave
asyncore/asynchat는 당신에게'select' 함수 호출 (보통 모든 비동기적인 것들이 빌드되는) 인 객체 지향 래퍼를 제공합니다. 'select'는 asyncore/asynchat가하는 것과 마찬가지로 파일 디스크립터에서 작동합니다. 몇 분만 있으면 무언가를 얻을 수 있습니다. –