1 # Copyright (c) 2011 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 connectionMade(self):
33 print "Started TCP Listener connection"
35 def dataReceived(self, data):
36 self.stats += len(data)
38 def connectionLost(self, reason):
39 print "Stopped TCP Listener connection"
40 self.factory.stats += self.stats
43 class TcpListenerFactory(Factory):
45 This per-listening socket class is used to
46 instantiate TcpListenerConnections
48 protocol = TcpListenerConnection
53 def startFactory(self):
54 print "Starting TCP listener factory"
56 def stopFactory(self):
57 print "Stopping TCP listener factory"
60 """ returns the number of bytes received as string"""
61 #XML RPC does not support 64bit int (http://bugs.python.org/issue2985)
62 #so we have to convert the amount of bytes into a string
63 return str(self.stats)
66 class Producer(object):
67 implements(interfaces.IPushProducer)
69 This producer class generates infinite byte stream for a specified time
72 def __init__(self, proto, duration):
74 self.start = time.time()
77 self.data = "X" * 65535
78 self.duration = duration
80 def pauseProducing(self):
81 """This function is called whenever write() to socket would block"""
84 def resumeProducing(self):
85 """This function is called whenever socket becomes writable"""
88 while (not self.paused) and (current < self.start + self.duration):
89 self.proto.transport.write(self.data)
90 self.produced += len(self.data)
92 if current >= self.start + self.duration:
93 self.proto.factory.stats += self.produced
94 self.proto.transport.unregisterProducer()
95 self.proto.transport.loseConnection()
97 def stopProducing(self):
101 class TcpSenderConnection(Protocol):
103 TCP connection instance class that sends all traffic at full speed.
106 def connectionMade(self):
107 print "Started TCP sender connection"
108 producer = Producer(self, self.factory.duration)
109 self.transport.registerProducer(producer, True)
110 producer.resumeProducing()
112 def dataReceived(self, data):
113 print "Sender received data!", data
114 self.transport.loseConnection()
116 def connectionLost(self, reason):
117 print "Stopped TCP sender connection"
120 class TcpSenderFactory(ClientFactory):
122 This factory is responsible to instantiate TcpSenderConnection classes
123 each time sender initiates connection
125 protocol = TcpSenderConnection
127 def __init__(self, duration):
128 self.duration = duration
131 def startFactory(self):
132 print "Starting TCP sender factory"
134 def stopFactory(self):
135 print "Stopping TCP sender factory"
137 def getResults(self):
138 """Returns amount of bytes sent to the Listener (as a string)"""
139 return str(self.stats)