twisted学习01-echo server and echo client

twisted的几个核心组件protocol,transport,factory,defer,reactor,把这几个关键组件搞清楚了,也就算是twisted入门了,大致关系是这样的由reactor来形成消息循环(和windows的消息循环机制类似),等到socket完成后通过defer(延迟通知技术,也就是基于这个事件的驱动),去调用相应的响应函数来实现异步操作。twisted的调用框架会首先找到监听(或连接,如果是客户端的话)的工厂,根据工厂的接口buildProtocol来构建相应的协议,其实最有必要的是去了解和研究twisted.internet的interfaces模块,这里模块讲解了所有组件的接口(这些接口均是从zope.inteferace衍生过来的),下面看下twisted.internet.interfaces的IProtocolFactory,ITransport,IProtocol接口类

class IProtocolFactory(Interface):
    """
    Interface for protocol factories.
    """

    def buildProtocol(addr):
        """
        Called when a connection has been established to addr.

        If None is returned, the connection is assumed to have been refused,
        and the Port will close the connection.

        @type addr: (host, port)
        @param addr: The address of the newly-established connection

        @return: None if the connection was refused, otherwise an object
                 providing L{IProtocol}.
        """

    def doStart():
        """
        Called every time this is connected to a Port or Connector.
        """

    def doStop():
        """
        Called every time this is unconnected from a Port or Connector.
        """

class ITransport(Interface):
    """
    I am a transport for bytes.

    I represent (and wrap) the physical connection and synchronicity
    of the framework which is talking to the network.  I make no
    representations about whether calls to me will happen immediately
    or require returning to a control loop, or whether they will happen
    in the same or another thread.  Consider methods of this class
    (aside from getPeer) to be 'thrown over the wall', to happen at some
    indeterminate time.

class IProtocol(Interface):

    def dataReceived(data):
        """
        Called whenever data is received.

        Use this method to translate to a higher-level message.  Usually, some
        callback will be made upon the receipt of each complete protocol
        message.

        @param data: a string of indeterminate length.  Please keep in mind
            that you will probably need to buffer some data, as partial
            (or multiple) protocol messages may be received!  I recommend
            that unit tests for protocols call through to this method with
            differing chunk sizes, down to one byte at a time.
        """

    def connectionLost(reason):
        """
        Called when the connection is shut down.

        Clear any circular references here, and any external references
        to this Protocol.  The connection has been closed. The C{reason}
        Failure wraps a L{twisted.internet.error.ConnectionDone} or
        L{twisted.internet.error.ConnectionLost} instance (or a subclass
        of one of those).

        @type reason: L{twisted.python.failure.Failure}
        """

    def makeConnection(transport):
        """
        Make a connection to a transport and a server.
        """

    def connectionMade():
        """
        Called when a connection is made.

        This may be considered the initializer of the protocol, because
        it is called when the connection is completed.  For clients,
        this is called once the connection to the server has been
        established; for servers, this is called after an accept() call
        stops blocking and a socket has been received.  If you need to
        send any greeting or initial message, do it here.
        """

这里提供了所有组件的核心接口。

下面看看我写的例子代码

echo_client.py

from twisted.internet.protocol import Protocol, ClientFactory
from twisted.internet.endpoints import clientFromString
from twisted.internet import reactor

class EchoClientProtocol(Protocol):
	def connectionMade(self):
		self.transport.write('> To Server:Hello server');
	def dataReceived(self, data):
		print('> From Server:%s' % data)
		reactor.stop()

class EchoClientFactory(ClientFactory):
	protocol = EchoClientProtocol

if __name__ == '__main__':
	#construct 10 client endpoints
	for i in xrange(10):
		clientFromString(reactor,'tcp:localhost:8888')				.connect(
						EchoClientFactory()
						)
	reactor.run()

echo_server.py

from twisted.internet.protocol import Protocol,Factory
from twisted.internet import reactor
from twisted.internet.endpoints import serverFromString

class EchoServerProtocol(Protocol):
	def connectionMade(self):
		print('> New connection made,from client!')
		self.factory.conn = self.factory.conn + 1
		print('> Now conn=%d' % self.factory.conn)

	def dataReceived(self, data):
		print('> Data from client: %s'% data)
		self.transport.write(data)

		print('>Host: ',repr(self.transport.getHost()))
		print('>Peer: ',repr(self.transport.getPeer()))
		#Close connection with client
		self.transport.loseConnection()
		self.factory.conn = self.factory.conn - 1

class EchoServerFactory(Factory):
	protocol = EchoServerProtocol
	def __init__(self):
		self.conn = 0

if __name__ == '__main__':
	serverFromString(reactor,'tcp:8888').			listen(
				EchoServerFactory()
					)
	reactor.run()

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-04 17:00:41

twisted学习01-echo server and echo client的相关文章

swoole深入学习 2. tcp Server和tcp Client

这节来学习Swoole最基础的Server和Client.会通过创建一个tcp Server来讲解. server <?php class Server { private $serv; public function __construct() { $this->serv = new Swoole\Server('127.0.0.1', 9501); //当启动一个Swoole应用时,一共会创建2 + n + m个进程,2为一个Master进程和一个Manager进程,其中n为Worker进

[z]libevent入门教程:Echo Server based on libevent 不指定

[z]https://www.felix021.com/blog/read.php?2068 花了两天的时间在libevent上,想总结下,就以写简单tutorial的方式吧,貌似没有一篇简单的说明,让人马上就能上手用的. 首先给出官方文档吧: http://libevent.org ,首页有个Programming with Libevent,里面是一节一节的介绍libevent,但是感觉信息量太大了,而且还是英文的-.-(当然,如果想好好用libevent,看看还是很有必要的),还有个Ref

libevent 入门教程:Echo Server based on libevent(转)

下面假定已经学习过基本的socket编程(socket, bind, listen, accept, connect, recv, send, close),并且对异步/callback有基本的认识. 基本的socket编程是阻塞/同步的,每个操作除非已经完成或者出错才会返回,这样对于每一个请求,要使用一个线程或者单独的进程去处理,系统资源没法支撑大量的请求.Posix定义了可以使用异步的select系统调用,但是因为其采用了轮询的方式来判断某个fd是否变成active,效率不高o(n).于是各

[UMU 学 golang](3) TCP Echo Server

测试需要,以前用 C + libevent 写了一个 TCP Echo Server,返回服务器时间.客户端地址信息和客户端发送的原内容.为了水一篇,现在改为 golang 实现. package main import ( "fmt" "io" "net" "os" "time" ) const BUFFER_SIZE = 1024 * 4 var buffer = make([]byte, BUFFER

libevent入门教程:Echo Server based on libevent - Blog of Felix021 - 日,泯然众人矣。

a:focus { outline: thin dotted #333; outline: 5px auto -webkit-focus-ring-color; outline-offset: -2px; } a:hover { outline: 0; } a:active { outline: 0; } a:hover { color: #005580 !important; text-decoration: underline !important; } blockquote small:b

Netty5 echo server练习

Netty5的架构比Netty4的架构及代码上都有很多的改进,看起来很清晰. 下面的根据官网例子改进的Echo Server例子代码. 代码中增加的有netty自带的hander,LineBasedFrameDecoder主要解决网络传输的粘包/拆包问题.StringDecoder和StringEncoder主要解决netty ByteBuf和string之间的转换. Netty in action 上也提到了几个注意事项:读取消息后,记得要释放,必须在finally块释放(父类ChannelH

[UMU 学 golang](5) HTTP Echo Server

做加速时经常需要用到 HTTP Echo Server 来测试加速有没有成功,如果成功了,是显示请求来自加速代理服务器.原来用 node.js 写了一个,代码如下: var http = require('http'); http.createServer( function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); var ip = req.headers['x-forwarded-for'] || req

php学习日志(3)-echo&amp;print

在php中,结果输出一共有两种方式:echo和print,下面将对两种方式做一个比较. echo与print的区别:   echo print 连续输出字符串 能连续输出多个字符串 只能输出一个字符串 返回值 无 返回1 用法 echo或echo() print或print() (1)echo能连续输出多个字符串,print只能输出一个字符串: 实例1: <?php /*echo能连续输出多个字符串,print只能输出一个字符串*/ echo "echo输出一个字符串:"; ec

SHELL脚本攻略(学习笔记)--1.2 echo和printf打印输出

1.2.1 echo的引号问题 关于echo的用法,注意点就是单引号和双引号的特殊情况.以打印“Hello World!”为例. [[email protected] tmp]# echo Hello World! Hello World! [[email protected] tmp]# echo 'Hello World!' Hello World! [[email protected] tmp]# echo "Hello World!" #双引号不能打印感叹号 -bash: !&

《批处理在提高Windows管理效率中神奇应用》学习01

<批处理在提高Windows管理效率中神奇应用>学习 ::1.3 ::echo. 显示空行 ::数值范围循环的for循环 @echo off echo Creating file0.txt ~ file99.txt echo. echo. :: for /l %%n in (0,1,99) /l表示for语句在指定的数值范围内循环.范围由in决定 ::in (0,1,99) 表示从0开始,步长为1,到99结束(包含99) for /l %%n in (0,1,99) do ( echo %%n