1 # Copyright (c) 2011, 2012 Nicira Networks
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at:
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
16 tcp module contains listener and sender classes for TCP protocol
19 from twisted.internet.protocol import Factory, ClientFactory, Protocol
20 from twisted.internet import interfaces
21 from zope.interface import implements
25 class TcpListenerConnection(Protocol):
27 This per-connection class is instantiated each time sender connects
32 def dataReceived(self, data):
33 self.stats += len(data)
35 def connectionLost(self, reason):
36 self.factory.stats += self.stats
39 class TcpListenerFactory(Factory):
41 This per-listening socket class is used to
42 instantiate TcpListenerConnections
44 protocol = TcpListenerConnection
50 """ returns the number of bytes received as string"""
51 # XML RPC does not support 64bit int (http://bugs.python.org/issue2985)
52 # so we have to convert the amount of bytes into a string
53 return str(self.stats)
56 class Producer(object):
57 implements(interfaces.IPushProducer)
59 This producer class generates infinite byte stream for a specified time
62 def __init__(self, proto, duration):
64 self.start = time.time()
67 self.data = "X" * 65535
68 self.duration = duration
70 def pauseProducing(self):
71 """This function is called whenever write() to socket would block"""
74 def resumeProducing(self):
75 """This function is called whenever socket becomes writable"""
78 while (not self.paused) and (current < self.start + self.duration):
79 self.proto.transport.write(self.data)
80 self.produced += len(self.data)
82 if current >= self.start + self.duration:
83 self.proto.factory.stats += self.produced
84 self.proto.transport.unregisterProducer()
85 self.proto.transport.loseConnection()
87 def stopProducing(self):
91 class TcpSenderConnection(Protocol):
93 TCP connection instance class that sends all traffic at full speed.
96 def connectionMade(self):
97 producer = Producer(self, self.factory.duration)
98 self.transport.registerProducer(producer, True)
99 producer.resumeProducing()
101 def dataReceived(self, data):
102 self.transport.loseConnection()
105 class TcpSenderFactory(ClientFactory):
107 This factory is responsible to instantiate TcpSenderConnection classes
108 each time sender initiates connection
110 protocol = TcpSenderConnection
112 def __init__(self, duration):
113 self.duration = duration
116 def getResults(self):
117 """Returns amount of bytes sent to the Listener (as a string)"""
118 return str(self.stats)