0.安装 Twisted
摘自http://blog.csdn.net/androidzhaoxiaogang/article/details/8479140
步骤1:下载Twisted
http://twistedmatrix.com/trac/wiki/Downloads
我下载的是(Twisted-12.3.0.win32-py2.7)
步骤2:安装Twisted
点击Twisted-12.3.0.win32-py2.7直接运行即可
步骤3:下载zope
http://pypi.python.org/pypi/zope.interface#downloads
我下载的是zope.interface-3.8.0-py2.7-win32.egg
步骤4:安装zope
http://pypi.python.org/pypi/setuptools
先下载setuptools-0.6c11.win32-py2.7.exe(http://pan.baidu.com/s/15R6w4), 安装setup tools
这是C:\Python27\Scripts下会有一些与easy_install相关的文件。
如果你已经安装了easy_install可以忽略上面的步骤。
将zope.interface-3.8.0-py2.7-win32.egg放到 C:\Python27\Scripts目录下。
在命令行中运行:
C:\>cd Python27\Scripts
C:\Python27\Scripts>easy_install.exe zope.interface-3.8.0-py2.7-win32.egg
1.Twisted框架构建简单的C/S
要写一个基于twisted框架的服务器,你要实现事件处理器,它处理诸如一个新的客户端连接、新的数据到达和客户端连接中断等情况。
在Twisted中,你的事件处理器定义在一个protocol中;你也需要一个factory,当一个新的连接到达时它能够构造这个protocol对象,但是如果你仅仅想创建一个自定义的Protocol类的实例的话,你可以使用来自Twisted的factory,Factory类在模块twisted.internet.protocol中。当你写你的protocol时,使用twisted.internet.protocol模块中的Protocol作为你的父类。
当你得到一个连接时,事件处理器connectionMade被调用;
当你丢失一个连接时,connectionLost被调用;
从客户端接受数据使用处理器dataReceived;
但是你不能使用事件处理策略向客户端发送数据;要向客户端发送数据,你可以使用self.transport,它有一个write方法。它也有一个client属性,其中包含了客户端的地址(主机名和端口),即self.transport.client。
Eg:
twisted server:
from twisted.internet import reactor
from twisted.internet.protocol import Protocol, Factory
# 定义你Protocol类
class SimpleLogger(Protocol):
def connectionMade(self):
print 'Got connection from', self.transport.client #self.transport.client =客户端主机名和端口
def connectionLost(self, reason):
print self.transport.client, 'disconnected'
def dataReceived(self, data):
print data
# 实例化Factory
factory = Factory()
# 设置factory的protocol属性以便它知道使用哪个protocol与客户端通信(这就是所谓的你的自定义
# protocol)
factory.protocol = SimpleLogger
# 监听指定的端口
reactor.listenTCP(1234, factory)
# 开始运行主程序
reactor.run()
测试的cilent端:
#socket client end
from socket import *
s=socket(AF_INET,SOCK_STREAM)
remote_host=gethostname()
print 'remote_ip:',remote_host
port=1234
s.connect((remote_host,port)) #发起连接
'''
socket对象的getpeername()和getsockname()方法都返回包含一个IP地址和端口的二元组
(这个二元组的形式就像你传递给connect和bind的)。
getpeername返回所连接的远程socket的地址和端口,getsockname返回关于本地socket的相同信息。
'''
print("Connected from",s.getsockname()) ##返回本地IP和端口
print("Connected to",s.getpeername()) ##返回服务端IP和端口
s.send('i am form client')
#print 'what i got from select server is:'
#print s.recv(1024)
'''
send,sendto,recv和recvfrom方法都有一个可选的参数flags,默认值为0。
你可以通过对socket.MSG_*变量进行组合(按位或)来建立flags的值。
这些值因平台而有所不同,但是最通用的值如下所示:
MSG_OOB:处理带外数据(既TCP紧急数据)。
MSG_DONTROUTE:不使用路由表;直接发送到接口。
MSG_PEEK:返回等待的数据且不把它们从队列中删除。
'''
运行结果:
server端:
>>> ================================ RESTART ================================
>>>
Got connection from ('172.22.144.167', 5466)
i am form client
client 端:
>>> ================================ RESTART ================================
>>>
remote_ip: PC-200910021344
('Connected from', ('172.22.144.167', 5466))
('Connected to', ('172.22.144.167', 1234))
>>>
2.自定义Protocol--利用LineReceiver类作为父类
模块twisted.protocols.basic中包含了几个有用的已存在的protocol,其中的LineReceiver执行dataReceived并在接受到了一个完整的行时调用事件处理器lineReceived。如果当你在接受数据时除了使用lineReceived,还要做些别的,那么你可以使用LineReceiver定义的名为rawDataReceived事件处理器。
Eg:
Server端:
from twisted.internet import reactor
from twisted.internet.protocol import Factory
from twisted.protocols.basic import LineReceiver
class SimpleLogger(LineReceiver):
def connectionMade(self):
print 'Got connection from', self.transport.client
def connectionLost(self, reason):
print self.transport.client, 'disconnected'
#注意必须接收到完整的行(即遇到\r\n结束标志)时该函数才能成功执行
def lineReceived(self, line):
print line
length=len(line)
responsemsg='Dear cilent,I have received '+str(length)+' bytes from you\r\n'
self.transport.write(responsemsg)#向客户端发送数据
factory = Factory()
factory.protocol = SimpleLogger
reactor.listenTCP(1234, factory)
reactor.run()
Client端:
#socket client end
from socket import *
s=socket(AF_INET,SOCK_STREAM)
remote_host=gethostname()
print 'remote_host:',remote_host
port=1234
s.connect((remote_host,port)) #发起连接
print("Connected from",s.getsockname()) ##返回本地IP和端口
print("Connected to",s.getpeername()) ##返回服务端IP和端口
s.send('i am form client\r\n')#发送一行字符串(以\r\n 结束)到服务器端
s.send('next message\r\n')
print 'the msg i got from select server is:'
print s.recv(1024)
运行结果:
Server端:
>>> ================================ RESTART ================================
>>>
Got connection from ('172.22.144.167', 9668)
i am form client
next message
Client端:
>>> ================================ RESTART ================================
>>>
remote_host: PC-200910021344
('Connected from', ('172.22.144.167', 9668))
('Connected to', ('172.22.144.167', 1234))
the msg i got from select server is:
Dear cilent,I have received 16 bytes from you
Dear cilent,I have received 12 bytes from you
>>>
3.使用twisted框架创建Web服务器
Web Server 端:
#Main Point:Build Web Server
from twisted.internet import protocol,reactor
from twisted.protocols import basic
class SimpleLogger(basic.LineReceiver):
def connectionMade(self):
print 'Got connection from', self.transport.client
def connectionLost(self, reason):
print self.transport.client, 'disconnected'
def lineReceived(self,line):
print 'data from client are as followings:'
print line
responseData="Welcome to Twisted World!\r\n"
self.transport.write(responseData)
self.transport.loseConnection() #终止连接
# 实例化protocol.ServerFactory()
'''
protocolp.py
class ServerFactory(Factory):
"""Subclass this to indicate that your protocol.Factory is only usable for servers.
"""
'''
factory = protocol.ServerFactory()# ***0120 protocol.ServerFactory()
factory.protocol = SimpleLogger
reactor.listenTCP(6688, factory)
reactor.run()
浏览器客户端测试结果:
Server端运行结果:
>>> ================================ RESTART ================================
>>>
Got connection from ('172.22.144.167', 10293)
Got connection from ('172.22.144.167', 10294)
Got connection from ('172.22.144.167', 10297)
data from client are as followings:
GET / HTTP/1.1
('172.22.144.167', 10297) disconnected
Got connection from ('172.22.144.167', 10298)
data from client are as followings:
GET /favicon.ico HTTP/1.1
('172.22.144.167', 10298) disconnected
('172.22.144.167', 10293) disconnected
('172.22.144.167', 10294) disconnected
4. http请求和响应报文
功能:
返回客户端的请求信息(http请求报文)
Web Server端代码:
from twisted.protocols import basic
from twisted.internet import protocol,reactor
class HttpEchoProtocol(basic.LineReceiver):
def __init__(self):
self.lines=[]
self.gotRequest=False
def lineReceived(self,line):
self.lines.append(line)
if not line and not self.gotRequest:
#0121
print 'the msg browser client send to me(http request head) is:'
for e in self.lines:
print e
#
self.sendResponse()
self.gotRequest=True
def sendResponse(self):
#0121 "\r\n".join(self.lines) 列表中的每一条请求消息字符串均用\r\n连接起来
responseBody="Dear Client,the msg you sent to me are as followings:\r\n\r\n"+"\r\n".join(self.lines)
#send msg to the browser client 0121
#http response head 0121
self.sendLine("HTTP/1.0 200 OK") #请求成功 0121 (必须) senfLine自动在消息字符串末尾添加\r\n
self.sendLine("Content-Type: text/plain")
self.sendLine("Content-Length: %i"%len(responseBody))
#下面两行语句[1][2]等价 #0121
#self.sendLine("") #http头结束标志 (必须) \r\n [1]
self.transport.write("\r\n") #[2]
self.transport.write(responseBody) #向客户端发送数据
self.transport.loseConnection() #终止连接
f=protocol.ServerFactory()
f.protocol=HttpEchoProtocol
reactor.listenTCP(5000,f)
reactor.run()
浏览器测试结果:
服务器端运行结果: