]>
Commit | Line | Data |
---|---|---|
e0edde6f | 1 | # Copyright (c) 2011, 2012 Nicira, Inc. |
0be6140a AA |
2 | # |
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: | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
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. | |
14 | ||
15 | """ | |
16 | ovsudp contains listener and sender classes for UDP protocol | |
17 | """ | |
18 | ||
8d25d9a2 AA |
19 | import array |
20 | import struct | |
21 | import time | |
22 | ||
0be6140a AA |
23 | from twisted.internet.protocol import DatagramProtocol |
24 | from twisted.internet.task import LoopingCall | |
0be6140a AA |
25 | |
26 | ||
27 | class UdpListener(DatagramProtocol): | |
28 | """ | |
29 | Class that will listen for incoming UDP packets | |
30 | """ | |
31 | def __init__(self): | |
32 | self.stats = [] | |
33 | ||
66d61c90 | 34 | def datagramReceived(self, data, _1_2): |
0be6140a AA |
35 | """This function is called each time datagram is received""" |
36 | try: | |
37 | self.stats.append(struct.unpack_from("Q", data, 0)) | |
38 | except struct.error: | |
8d25d9a2 | 39 | pass # ignore packets that are less than 8 bytes of size |
0be6140a AA |
40 | |
41 | def getResults(self): | |
42 | """Returns number of packets that were actually received""" | |
43 | return len(self.stats) | |
44 | ||
45 | ||
46 | class UdpSender(DatagramProtocol): | |
47 | """ | |
48 | Class that will send UDP packets to UDP Listener | |
49 | """ | |
50 | def __init__(self, host, count, size, duration): | |
8d25d9a2 | 51 | # LoopingCall does not know whether UDP socket is actually writable |
0be6140a AA |
52 | self.looper = None |
53 | self.host = host | |
54 | self.count = count | |
55 | self.duration = duration | |
56 | self.start = time.time() | |
57 | self.sent = 0 | |
58 | self.data = array.array('c', 'X' * size) | |
59 | ||
60 | def startProtocol(self): | |
0be6140a AA |
61 | self.looper = LoopingCall(self.sendData) |
62 | period = self.duration / float(self.count) | |
a0631d92 | 63 | self.looper.start(period, now=False) |
0be6140a AA |
64 | |
65 | def stopProtocol(self): | |
0be6140a AA |
66 | if (self.looper is not None): |
67 | self.looper.stop() | |
68 | self.looper = None | |
69 | ||
66d61c90 | 70 | def datagramReceived(self, data, host_port): |
0be6140a AA |
71 | pass |
72 | ||
73 | def sendData(self): | |
74 | """This function is called from LoopingCall""" | |
75 | if self.start + self.duration < time.time(): | |
76 | self.looper.stop() | |
77 | self.looper = None | |
78 | ||
79 | self.sent += 1 | |
80 | struct.pack_into('Q', self.data, 0, self.sent) | |
81 | self.transport.write(self.data, self.host) | |
82 | ||
83 | def getResults(self): | |
84 | """Returns number of packets that were sent""" | |
85 | return self.sent |