python twisted 筆記

1.Twisted框架構建簡單的C/Sreact

要寫一個基於twisted框架的服務器,你要實現事件處理器,它處理諸如一個新的客戶端鏈接、新的數據到達和客戶端鏈接中斷等狀況瀏覽器

在Twisted中,你的事件處理器定義在一個protocol中;你也須要一個factory, 當一個新的鏈接到達時它可以構造這個protocol對象,可是若是你僅僅想建立一個自定義的Protocol類的實例的話,你可使用來自 Twisted的factory,Factory類在模塊twisted.internet.protocol中。當你寫你的protocol時,使用twisted.internet.protocol模塊中的Protocol做爲你的父類服務器

當你獲得一個鏈接時,事件處理器connectionMade被調用;架構

當你丟失一個鏈接時,connectionLost被調用;app

客戶端接受數據使用處理器dataReceived框架

可是你不能使用事件處理策略向客戶端發送數據;要向客戶端發送數據,你能夠使用self.transport,它有一個write方法。它也有一個client屬性,其中包含了客戶端的地址(主機名和端口),即self.transport.clientsocket


Eg:函數

twisted server:測試

[cpp]
ui

  1. from twisted.internet import reactor  

  2. from twisted.internet.protocol import Protocol, Factory  

  3.   

  4. # 定義你Protocol類  

  5. class SimpleLogger(Protocol):  

  6.     def connectionMade(self):  

  7.         print 'Got connection from', self.transport.client #self.transport.client =客戶端主機名和端口  

  8.     def connectionLost(self, reason):  

  9.         print self.transport.client, 'disconnected'  

  10.     def dataReceived(self, data):  

  11.         print data  

  12.   

  13. # 實例化Factory  

  14. factory = Factory()  

  15.   

  16. # 設置factory的protocol屬性以便它知道使用哪一個protocol與客戶端通訊(這就是所謂的你的自定義  

  17. # protocol)  

  18. factory.protocol = SimpleLogger  

  19.   

  20. # 監聽指定的端口  

  21. reactor.listenTCP(1234, factory)  

  22.   

  23. # 開始運行主程序  

  24. reactor.run()  


測試的cilent端:

[cpp] 

  1. #socket client end  

  2.   

  3. from socket import *  

  4.   

  5. s=socket(AF_INET,SOCK_STREAM)  

  6.   

  7. remote_host=gethostname()  

  8. print 'remote_ip:',remote_host  

  9. port=1234  

  10. s.connect((remote_host,port)) #發起鏈接  

  11. '''  

  12. socket對象的getpeername()和getsockname()方法都返回包含一個IP地址和端口的二元組  

  13. (這個二元組的形式就像你傳遞給connect和bind的)。  

  14. getpeername返回所鏈接的遠程socket的地址和端口,getsockname返回關於本地socket的相同信息。  

  15. '''  

  16. print("Connected from",s.getsockname()) ##返回本地IP和端口  

  17. print("Connected to",s.getpeername())  ##返回服務端IP和端口  

  18.   

  19. s.send('i am form client')  

  20.   

  21. #print 'what i got from select server is:'  

  22. #print s.recv(1024)  

  23. '''  

  24. send,sendto,recv和recvfrom方法都有一個可選的參數flags,默認值爲0。  

  25. 你能夠經過對socket.MSG_*變量進行組合(按位或)來創建flags的值。  

  26. 這些值因平臺而有所不一樣,可是最通用的值以下所示:  

  27.   

  28. MSG_OOB:處理帶外數據(既TCP緊急數據)。  

  29. MSG_DONTROUTE:不使用路由表;直接發送到接口。  

  30. MSG_PEEK:返回等待的數據且不把它們從隊列中刪除。  

  31.   

  32. '''  


運行結果:

server端:

[cpp]

  1. >>> ================================ RESTART ================================  

  2. >>>   

  3. Got connection from ('172.22.144.167', 5466)  

  4. i am form client  


client 端:

[cpp]

  1. >>> ================================ RESTART ================================  

  2. >>>   

  3. remote_ip: PC-200910021344  

  4. ('Connected from', ('172.22.144.167', 5466))  

  5. ('Connected to', ('172.22.144.167', 1234))  

  6. >>>   


2.自定義Protocol--利用LineReceiver類做爲父類

模塊twisted.protocols.basic中包含了幾個有用的已存在的protocol,其中的LineReceiver執行dataReceived並在接受到了一個完整的行時調用事件處理器lineReceived。若是當你在接受數據時除了使用lineReceived,還要作些別的,那麼你可使用LineReceiver定義的名爲rawDataReceived事件處理器。

Eg:

Server端:

[cpp]

  1. from twisted.internet import reactor  

  2. from twisted.internet.protocol import Factory  

  3. from twisted.protocols.basic import LineReceiver  

  4.   

  5. class SimpleLogger(LineReceiver):  

  6.   

  7.     def connectionMade(self):  

  8.         print 'Got connection from', self.transport.client  

  9.     def connectionLost(self, reason):  

  10.         print self.transport.client, 'disconnected'  

  11.     #注意必須接收到完整的行(即遇到\r\n結束標誌)時該函數才能成功執行   

  12.     def lineReceived(self, line):  

  13.         print line  

  14.         length=len(line)  

  15.         responsemsg='Dear cilent,I have received '+str(length)+' bytes from you\r\n'  

  16.         self.transport.write(responsemsg)#向客戶端發送數據  

  17.   

  18. factory = Factory()  

  19. factory.protocol = SimpleLogger  

  20. reactor.listenTCP(1234, factory)  

  21. reactor.run()   

Client端:

[cpp] 

  1. #socket client end  

  2. from socket import *  

  3.   

  4. s=socket(AF_INET,SOCK_STREAM)  

  5. remote_host=gethostname()  

  6. print 'remote_host:',remote_host  

  7. port=1234  

  8. s.connect((remote_host,port)) #發起鏈接  

  9. print("Connected from",s.getsockname()) ##返回本地IP和端口  

  10. print("Connected to",s.getpeername())  ##返回服務端IP和端口  

  11. s.send('i am form client\r\n')#發送一行字符串(以\r\n 結束)到服務器端   

  12. s.send('next message\r\n')  

  13.   

  14. print 'the msg i got from select server is:'  

  15. print s.recv(1024)  

運行結果:

Server端:

[cpp] 

  1. >>> ================================ RESTART ================================  

  2. >>>   

  3. Got connection from ('172.22.144.167', 9668)  

  4. i am form client  

  5. next message  

Client端:

[cpp] 

  1. >>> ================================ RESTART ================================  

  2. >>>   

  3. remote_host: PC-200910021344  

  4. ('Connected from', ('172.22.144.167', 9668))  

  5. ('Connected to', ('172.22.144.167', 1234))  

  6. the msg i got from select server is:  

  7. Dear cilent,I have received 16 bytes from you  

  8.   

  9. Dear cilent,I have received 12 bytes from you  

  10.   

  11.   

  12. >>>   


3.使用twisted框架建立Web服務器

Web Server 端:

[cpp]

  1. #Main Point:Build Web Server  

  2.   

  3. from twisted.internet import protocol,reactor  

  4. from twisted.protocols import basic  

  5.   

  6. class SimpleLogger(basic.LineReceiver):  

  7.     def connectionMade(self):  

  8.         print 'Got connection from', self.transport.client  

  9.           

  10.     def connectionLost(self, reason):  

  11.         print self.transport.client, 'disconnected'  

  12.         

  13.     def lineReceived(self,line):  

  14.         print 'data from client are as followings:'  

  15.         print line  

  16.         responseData="Welcome to Twisted World!\r\n"  

  17.         self.transport.write(responseData)  

  18.         self.transport.loseConnection()  #終止鏈接  

  19.   

  20. # 實例化protocol.ServerFactory()  

  21. '''  

  22. protocolp.py  

  23. class ServerFactory(Factory):  

  24.     """Subclass this to indicate that your protocol.Factory is only usable for servers.  

  25.     """  

  26. '''  

  27. factory = protocol.ServerFactory()#  ***0120 protocol.ServerFactory()  

  28. factory.protocol = SimpleLogger  

  29. reactor.listenTCP(6688, factory)  

  30. reactor.run()  


瀏覽器客戶端測試結果:

Server端運行結果:

[cpp] view plaincopy在CODE上查看代碼片派生到個人代碼片

  1. >>> ================================ RESTART ================================  

  2. >>>   

  3. Got connection from ('172.22.144.167', 10293)  

  4. Got connection from ('172.22.144.167', 10294)  

  5. Got connection from ('172.22.144.167', 10297)  

  6. data from client are as followings:  

  7. GET / HTTP/1.1  

  8. ('172.22.144.167', 10297) disconnected  

  9. Got connection from ('172.22.144.167', 10298)  

  10. data from client are as followings:  

  11. GET /favicon.ico HTTP/1.1  

  12. ('172.22.144.167', 10298) disconnected  

  13. ('172.22.144.167', 10293) disconnected  

  14. ('172.22.144.167', 10294) disconnected  

 

4. http請求和響應報文

功能:

返回客戶端的請求信息(http請求報文)

Web Server端代碼:

[cpp] view plaincopy在CODE上查看代碼片派生到個人代碼片

  1. from twisted.protocols import basic  

  2. from twisted.internet import protocol,reactor  

  3. class HttpEchoProtocol(basic.LineReceiver):  

  4.     def __init__(self):  

  5.         self.lines=[]  

  6.         self.gotRequest=False  

  7.     def lineReceived(self,line):   

  8.         self.lines.append(line)  

  9.         if not line and not self.gotRequest:  

  10.             #0121  

  11.             print 'the msg browser client send to me(http request head) is:'  

  12.             for e in self.lines:  

  13.                 print e  

  14.             #  

  15.             self.sendResponse()  

  16.             self.gotRequest=True  

  17.     def sendResponse(self):  

  18.         #0121 "\r\n".join(self.lines)  列表中的每一條請求消息字符串均用\r\n鏈接起來  

  19.         responseBody="Dear Client,the msg you sent to me are as followings:\r\n\r\n"+"\r\n".join(self.lines)  

  20.           

  21.         #send msg to the browser client  0121  

  22.         #http response head 0121  

  23.         self.sendLine("HTTP/1.0 200 OK")  #請求成功 0121 (必須) senfLine自動在消息字符串末尾添加\r\n  

  24.         self.sendLine("Content-Type: text/plain")  

  25.         self.sendLine("Content-Length: %i"%len(responseBody))  

  26.         #下面兩行語句[1][2]等價  #0121  

  27.         #self.sendLine("") #http頭結束標誌  (必須) \r\n  [1]  

  28.         self.transport.write("\r\n") #[2]  

  29.           

  30.         self.transport.write(responseBody) #向客戶端發送數據  

  31.         self.transport.loseConnection()  #終止鏈接  

  32.           

  33. f=protocol.ServerFactory()  

  34. f.protocol=HttpEchoProtocol  

  35. reactor.listenTCP(5000,f)  

  36. reactor.run()  


瀏覽器測試結果:


服務器端運行結果:

相關文章
相關標籤/搜索