扭曲在幾乎每一種可能的方式都更好。它更便攜,更功能,更簡單,更具可擴展性,更好的維護,更好的記錄,並且可以製作美味的煎蛋。 Asyncore對於所有的意圖和目的都是過時的。
很難證明其扭曲的優越在很短的答案(我怎麼能證明在很短的示例http/dns/ssh/smtp/pop/imap/irc/xmpp/process-spawning/multi-threading服務器?)的所有方式,所以不是我我們將專注於人們對扭曲的一種最常見的誤解:它比異化更復雜或更難以使用。
讓我們從一個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()
有一對夫婦的事情,我想請你注意。首先,扭曲的例子縮短了25%,即使是這樣的小事。 asyncore有40行,Twisted只有30行。隨着協議變得越來越複雜,這種差異將越來越大,因爲您需要爲Twisted提供的asyncore編寫越來越多的支持代碼。
二,扭曲提供了一個完整的抽象。使用asyncore示例,您必須使用socket
模塊來執行實際的網絡連接; asyncore只提供多路複用。這是一個問題,如果你需要portable behavior on platforms such as Windows。這也意味着asyncore完全缺乏在其他平臺上進行異步子進程通信的設施;您無法將任意文件描述符填入Windows上的select()
調用中。
三,扭曲的例子是運輸中立。 Echo
和EchoFactory
和EchoClient
和EchoClientFactory
都不是特定於TCP的。只有通過更改底部的一個呼叫,才能將這些類創建爲可通過SSH,SSL或UNIX套接字或管道連接的庫。這很重要,因爲直接在協議邏輯中支持像TLS這樣的技術非常棘手。例如,TLS中的「寫入」將觸發較低級別的「讀取」。所以,你需要將這些擔憂分開來讓它們正確。
最後,針對您的使用案例,如果您直接處理MAC地址和以太網幀,Twisted包含用於處理IP和以太網網絡的低級庫Twisted Pair。這不是Twisted最主要的維護部分;代碼是相當古老的。但是,它應該起作用,如果不行,我們會嚴肅對待任何錯誤,並且(最終)看到它們得到修復。據我所知,沒有可比較的庫asyncore,它當然不包含任何這樣的代碼本身。
爲什麼-1? ... – 2010-12-08 07:41:26
asyncore/asynchat似乎只在直接綁定到套接字處理時纔有用。在我的代碼中,`sniffer`處理所有套接字併產生結果。我希望asyncore做的就是運行我的`first`和`second`函數,並在`sniffer`返回數據時允許我發出回調。我將如何做到這一點? (我沒有downvote你,順便說一句) – dave 2010-12-08 07:47:52