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()  


浏览器测试结果:


服务器端运行结果:

相关文章
相关标签/搜索