建立一個Twisted Reactor TCP客戶端

iteye_21202發表於2013-05-16

與SocketServer TCP客戶端不一樣的是,這個例子與之前的所有其他客戶端看上去都不大一樣。它是完全Twisted的。

例16.8 Twisted Reactor Timestamp TCP客戶端(tsTclntTW.py)

用Twisted重寫我們已經熟悉的時間戳TCP客戶端。

1#!/usr/bin/env python
2
3from twisted.internet import protocol, reactor
4
5 HOST=' localhost '
6 PORT=21567
7
8class TSClntProtocol(protocol.Protocol):
9 def sendData(self):
data = raw_input('> ')
11 if data:
12 print '...sending %s...' % data
13 self.transport.write(data)
14 else:
15 self.transport.loseConnection()
16
17 def connectionMade(self):
18 self.sendData()
19
20 def dataReceived(self, data):
21 print data
22 self.sendData()
23
24 class TSClntFactory(protocol.ClientFactory):
25 protocol = TSClntProtocol
26 clientConnectionLost = clientConnectionFailed = \
27 lambda self, connector, reason: reactor.stop()
28
29 reactor.connectTCP(HOST, PORT, TSClntFactory())
30 reactor.run()

逐行解釋

1~6行

跟之前所有的客戶端程式類似,這裡還是匯入Twisted的元件。

8~22行

與伺服器一樣,我們擴充套件Protocol,重寫同樣的函式connectionMade()和dataReceived()。這兩個函式的用途也跟伺服器一樣。我們新加一個自己的函式sendData(),用於在需要傳送資料時呼叫。

由於我們現在是客戶端,所以我們要主動發起跟伺服器的對話。一旦連線建立好之後,我們先傳送一個訊息,伺服器回覆這個訊息,我們把收到的回覆顯示在螢幕上,然後再傳送其他訊息給伺服器。

這個過程會一直迴圈,直到使用者沒有給任何輸入時,連線結束。結束時,就不是呼叫transport物件的write()函式傳資料給伺服器了,而是呼叫loseConnection()函式來關閉套接字。這時,工廠的client ConnectionLost()函式會被呼叫,同時,reactor就被關閉,指令碼的執行就結束了。由於某些原因,clientConnectionFailed()被呼叫時,reactor也會被關閉。

指令碼的最後一部分是建立一個客戶端工廠,連線到伺服器,然後執行reactor。注意,我們在這裡例項化了客戶端工廠,而不是像在伺服器裡那樣把它傳到reactor中。這是因為,我們不是等待客戶端連線的伺服器,伺服器在有連線時要為每個連線建立一個新的protocol物件。我們只是一個客戶端,所以我們只要建立一個protocol物件,連線到伺服器,伺服器的工廠會建立一個protocol物件來與我們對話。

相關文章