~soren/nova/iptables-security-groups

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/doc/core/howto/udp.html

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html  PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN'  'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
 
2
  <head>
 
3
<title>Twisted Documentation: UDP Networking</title>
 
4
<link href="stylesheet.css" rel="stylesheet" type="text/css"/>
 
5
  </head>
 
6
 
 
7
  <body bgcolor="white">
 
8
    <h1 class="title">UDP Networking</h1>
 
9
    <div class="toc"><ol><li><a href="#auto0">Overview</a></li><li><a href="#auto1">DatagramProtocol</a></li><li><a href="#auto2">Connected UDP</a></li><li><a href="#auto3">Multicast UDP</a></li><li><a href="#auto4">Acknowledgements</a></li></ol></div>
 
10
    <div class="content">
 
11
    <span/>
 
12
    
 
13
    <h2>Overview<a name="auto0"/></h2>
 
14
    
 
15
    <p>Unlike TCP, UDP has no notion of connections. A UDP socket can receive
 
16
    datagrams from any server on the network, and send datagrams to any host
 
17
    on the network. In addition, datagrams may arrive in any order, never
 
18
    arrive at all, or be duplicated in transit.</p>
 
19
 
 
20
    <p>Since there are no multiple connections, we only use a single object,
 
21
    a protocol, for each UDP socket. We then use the reactor to connect
 
22
    this protocol to a UDP transport, using the 
 
23
    <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.internet.interfaces.IReactorUDP.html" title="twisted.internet.interfaces.IReactorUDP">twisted.internet.interfaces.IReactorUDP</a></code>
 
24
    reactor API.</p>
 
25
    
 
26
    <h2>DatagramProtocol<a name="auto1"/></h2>
 
27
 
 
28
    <p>At the base, the place where you actually implement the protocol
 
29
    parsing and handling, is the DatagramProtocol class. This class will
 
30
    usually be decended from <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.internet.protocol.DatagramProtocol.html" title="twisted.internet.protocol.DatagramProtocol">twisted.internet.protocol.DatagramProtocol</a></code>. Most
 
31
    protocol handlers inherit either from this class or from one of its
 
32
    convenience children. The DatagramProtocol class receives datagrams, and
 
33
    can send them out over the network. Received datagrams include the
 
34
    address they were sent from, and when sending datagrams the address to
 
35
    send to must be specified.</p>
 
36
    
 
37
    <p>Here is a simple example:</p>
 
38
    <pre class="python"><p class="py-linenumber"> 1
 
39
 2
 
40
 3
 
41
 4
 
42
 5
 
43
 6
 
44
 7
 
45
 8
 
46
 9
 
47
10
 
48
11
 
49
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span>.<span class="py-src-variable">protocol</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">DatagramProtocol</span>
 
50
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">reactor</span>
 
51
 
 
52
<span class="py-src-keyword">class</span> <span class="py-src-identifier">Echo</span>(<span class="py-src-parameter">DatagramProtocol</span>):
 
53
    
 
54
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">datagramReceived</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">data</span>, (<span class="py-src-parameter">host</span>, <span class="py-src-parameter">port</span>)):
 
55
        <span class="py-src-keyword">print</span> <span class="py-src-string">&quot;received %r from %s:%d&quot;</span> % (<span class="py-src-variable">data</span>, <span class="py-src-variable">host</span>, <span class="py-src-variable">port</span>)
 
56
        <span class="py-src-variable">self</span>.<span class="py-src-variable">transport</span>.<span class="py-src-variable">write</span>(<span class="py-src-variable">data</span>, (<span class="py-src-variable">host</span>, <span class="py-src-variable">port</span>))
 
57
 
 
58
<span class="py-src-variable">reactor</span>.<span class="py-src-variable">listenUDP</span>(<span class="py-src-number">9999</span>, <span class="py-src-variable">Echo</span>())
 
59
<span class="py-src-variable">reactor</span>.<span class="py-src-variable">run</span>()
 
60
</pre>
 
61
    
 
62
    <p>As you can see, the protocol is registed with the reactor. This means
 
63
    it may be persisted if it's added to an application, and thus it has
 
64
    <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.internet.protocol.DatagramProtocol.startProtocol.html" title="twisted.internet.protocol.DatagramProtocol.startProtocol">twisted.internet.protocol.DatagramProtocol.startProtocol</a></code>
 
65
    and <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.internet.protocol.DatagramProtocol.stopProtocol.html" title="twisted.internet.protocol.DatagramProtocol.stopProtocol">twisted.internet.protocol.DatagramProtocol.stopProtocol</a></code>
 
66
    methods that will get called when the protocol is connected and
 
67
    disconnected from a UDP socket.</p>
 
68
 
 
69
    <p>The protocol's <code class="python">transport</code> attribute will
 
70
    implement the <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.internet.interfaces.IUDPTransport.html" title="twisted.internet.interfaces.IUDPTransport">twisted.internet.interfaces.IUDPTransport</a></code> interface.
 
71
    Notice that the <code class="python">host</code> argument should be an
 
72
    IP, not a hostname. If you only have the hostname use <code class="python">reactor.resolve()</code> to resolve the address (see <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.internet.interfaces.IReactorCore.resolve.html" title="twisted.internet.interfaces.IReactorCore.resolve">twisted.internet.interfaces.IReactorCore.resolve</a></code>).</p>
 
73
 
 
74
 
 
75
    <h2>Connected UDP<a name="auto2"/></h2>
 
76
 
 
77
    <p>A connected UDP socket is slighly different from a standard one - it
 
78
    can only send and receive datagrams to/from a single address, but this
 
79
    does not in any way imply a connection. Datagrams may still arrive in any
 
80
    order, and the port on the other side may have no one listening. The
 
81
    benefit of the connected UDP socket is that it it <strong>may</strong>
 
82
    provide notification of undelivered packages. This depends on many
 
83
    factors, almost all of which are out of the control of the application,
 
84
    but it still presents certain benefits which occassionally make it
 
85
    useful.</p>
 
86
 
 
87
    <p>Unlike a regular UDP protocol, we do not need to specify where to
 
88
    send datagrams to, and are not told where they came from since
 
89
    they can only come from address the socket is 'connected' to.</p>
 
90
 
 
91
    <pre class="python"><p class="py-linenumber"> 1
 
92
 2
 
93
 3
 
94
 4
 
95
 5
 
96
 6
 
97
 7
 
98
 8
 
99
 9
 
100
10
 
101
11
 
102
12
 
103
13
 
104
14
 
105
15
 
106
16
 
107
17
 
108
18
 
109
19
 
110
20
 
111
21
 
112
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span>.<span class="py-src-variable">protocol</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">DatagramProtocol</span>
 
113
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">reactor</span>
 
114
 
 
115
<span class="py-src-keyword">class</span> <span class="py-src-identifier">Helloer</span>(<span class="py-src-parameter">DatagramProtocol</span>):
 
116
 
 
117
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">startProtocol</span>(<span class="py-src-parameter">self</span>):
 
118
        <span class="py-src-variable">self</span>.<span class="py-src-variable">transport</span>.<span class="py-src-variable">connect</span>(<span class="py-src-string">&quot;192.168.1.1&quot;</span>, <span class="py-src-number">1234</span>)
 
119
        <span class="py-src-keyword">print</span> <span class="py-src-string">&quot;we can only send to %s now&quot;</span> % <span class="py-src-variable">str</span>((<span class="py-src-variable">host</span>, <span class="py-src-variable">port</span>))
 
120
        <span class="py-src-variable">self</span>.<span class="py-src-variable">transport</span>.<span class="py-src-variable">write</span>(<span class="py-src-string">&quot;hello&quot;</span>) <span class="py-src-comment"># no need for address</span>
 
121
        
 
122
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">datagramReceived</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">data</span>, (<span class="py-src-parameter">host</span>, <span class="py-src-parameter">port</span>)):
 
123
        <span class="py-src-keyword">print</span> <span class="py-src-string">&quot;received %r from %s:%d&quot;</span> % (<span class="py-src-variable">data</span>, <span class="py-src-variable">host</span>, <span class="py-src-variable">port</span>)
 
124
 
 
125
    <span class="py-src-comment"># Possibly invoked if there is no server listening on the</span>
 
126
    <span class="py-src-comment"># address to which we are sending.</span>
 
127
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">connectionRefused</span>(<span class="py-src-parameter">self</span>):
 
128
        <span class="py-src-keyword">print</span> <span class="py-src-string">&quot;No one listening&quot;</span>
 
129
 
 
130
<span class="py-src-comment"># 0 means any port, we don't care in this case</span>
 
131
<span class="py-src-variable">reactor</span>.<span class="py-src-variable">listenUDP</span>(<span class="py-src-number">0</span>, <span class="py-src-variable">Helloer</span>())
 
132
<span class="py-src-variable">reactor</span>.<span class="py-src-variable">run</span>()
 
133
</pre>
 
134
 
 
135
    <p>Note that <code class="python">connect()</code>, like <code class="python">write()</code> will only accept IP addresses, not
 
136
    unresolved domain names. To obtain the IP of a domain name use <code class="python">reactor.resolve()</code>, e.g.:</p>
 
137
 
 
138
  <pre class="python"><p class="py-linenumber">1
 
139
2
 
140
3
 
141
4
 
142
5
 
143
6
 
144
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">reactor</span>
 
145
 
 
146
<span class="py-src-keyword">def</span> <span class="py-src-identifier">gotIP</span>(<span class="py-src-parameter">ip</span>):
 
147
    <span class="py-src-keyword">print</span> <span class="py-src-string">&quot;IP of 'example.com' is&quot;</span>, <span class="py-src-variable">ip</span>
 
148
 
 
149
<span class="py-src-variable">reactor</span>.<span class="py-src-variable">resolve</span>(<span class="py-src-string">'example.com'</span>).<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">gotIP</span>)
 
150
</pre>
 
151
 
 
152
    <p>Connecting to a new address after a previous connection, or
 
153
    making a connected port unconnected are not currently supported,
 
154
    but will likely be supported in the future.</p>
 
155
 
 
156
    <h2>Multicast UDP<a name="auto3"/></h2>
 
157
 
 
158
    <p>A multicast UDP socket can send and receive datagrams from multiple clients.
 
159
    The interesting and useful feature of the multicast is that a client can
 
160
    contact multiple servers with a single packet, without knowing the specific IP
 
161
    of any of the hosts.</p>
 
162
    
 
163
    <div class="py-listing"><pre><p class="py-linenumber"> 1
 
164
 2
 
165
 3
 
166
 4
 
167
 5
 
168
 6
 
169
 7
 
170
 8
 
171
 9
 
172
10
 
173
11
 
174
12
 
175
13
 
176
14
 
177
15
 
178
16
 
179
17
 
180
18
 
181
19
 
182
20
 
183
21
 
184
22
 
185
23
 
186
24
 
187
25
 
188
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span>.<span class="py-src-variable">protocol</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">DatagramProtocol</span>
 
189
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">reactor</span>
 
190
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">application</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">MulticastServer</span>
 
191
 
 
192
<span class="py-src-keyword">class</span> <span class="py-src-identifier">MulticastServerUDP</span>(<span class="py-src-parameter">DatagramProtocol</span>):
 
193
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">startProtocol</span>(<span class="py-src-parameter">self</span>):
 
194
        <span class="py-src-keyword">print</span> <span class="py-src-string">'Started Listening'</span>
 
195
        <span class="py-src-comment"># Join a specific multicast group, which is the IP we will respond to</span>
 
196
        <span class="py-src-variable">self</span>.<span class="py-src-variable">transport</span>.<span class="py-src-variable">joinGroup</span>(<span class="py-src-string">'224.0.0.1'</span>)
 
197
 
 
198
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">datagramReceived</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">datagram</span>, <span class="py-src-parameter">address</span>):
 
199
        <span class="py-src-comment"># The uniqueID check is to ensure we only service requests from</span>
 
200
        <span class="py-src-comment"># ourselves</span>
 
201
        <span class="py-src-keyword">if</span> <span class="py-src-variable">datagram</span> == <span class="py-src-string">'UniqueID'</span>:
 
202
            <span class="py-src-keyword">print</span> <span class="py-src-string">&quot;Server Received:&quot;</span> + <span class="py-src-variable">repr</span>(<span class="py-src-variable">datagram</span>)
 
203
            <span class="py-src-variable">self</span>.<span class="py-src-variable">transport</span>.<span class="py-src-variable">write</span>(<span class="py-src-string">&quot;data&quot;</span>, <span class="py-src-variable">address</span>)
 
204
 
 
205
<span class="py-src-comment"># Note that the join function is picky about having a unique object</span>
 
206
<span class="py-src-comment"># on which to call join.  To avoid using startProtocol, the following is</span>
 
207
<span class="py-src-comment"># sufficient:</span>
 
208
<span class="py-src-comment">#reactor.listenMulticast(8005, MulticastServerUDP()).join('224.0.0.1')</span>
 
209
 
 
210
<span class="py-src-comment"># Listen for multicast on 224.0.0.1:8005</span>
 
211
<span class="py-src-variable">reactor</span>.<span class="py-src-variable">listenMulticast</span>(<span class="py-src-number">8005</span>, <span class="py-src-variable">MulticastServerUDP</span>())
 
212
<span class="py-src-variable">reactor</span>.<span class="py-src-variable">run</span>()
 
213
</pre><div class="caption">Source listing - <a href="listings/udp/MulticastServer.py"><span class="filename">listings/udp/MulticastServer.py</span></a></div></div>
 
214
 
 
215
    <p>
 
216
    The server protocol is very simple, and closely resembles a normal listenUDP
 
217
    implementation.  The main difference is that instead of listenUDP,
 
218
    listenMulticast is called with a specified port number.  The server must also
 
219
    call joinGroup to specify on which multicast IP address it will service
 
220
    requests.  Another item of interest is the contents of the datagram.  Many
 
221
    different applications use multicast as a way of device discovery, which leads
 
222
    to an abundance of packets flying around.  Checking the payload can ensure
 
223
    that we only service requests from our specific clients.
 
224
    </p>
 
225
 
 
226
    <div class="py-listing"><pre><p class="py-linenumber"> 1
 
227
 2
 
228
 3
 
229
 4
 
230
 5
 
231
 6
 
232
 7
 
233
 8
 
234
 9
 
235
10
 
236
11
 
237
12
 
238
13
 
239
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span>.<span class="py-src-variable">protocol</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">DatagramProtocol</span>
 
240
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">reactor</span>
 
241
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">application</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">MulticastServer</span>
 
242
 
 
243
<span class="py-src-keyword">class</span> <span class="py-src-identifier">MulticastClientUDP</span>(<span class="py-src-parameter">DatagramProtocol</span>):
 
244
 
 
245
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">datagramReceived</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">datagram</span>, <span class="py-src-parameter">address</span>):
 
246
            <span class="py-src-keyword">print</span> <span class="py-src-string">&quot;Received:&quot;</span> + <span class="py-src-variable">repr</span>(<span class="py-src-variable">datagram</span>)
 
247
 
 
248
<span class="py-src-comment"># Send multicast on 224.0.0.1:8005, on our dynamically allocated port</span>
 
249
<span class="py-src-variable">reactor</span>.<span class="py-src-variable">listenUDP</span>(<span class="py-src-number">0</span>, <span class="py-src-variable">MulticastClientUDP</span>()).<span class="py-src-variable">write</span>(<span class="py-src-string">'UniqueID'</span>,
 
250
                                                 (<span class="py-src-string">'224.0.0.1'</span>, <span class="py-src-number">8005</span>))
 
251
<span class="py-src-variable">reactor</span>.<span class="py-src-variable">run</span>()
 
252
</pre><div class="caption">MulticastServer.py - <a href="listings/udp/MulticastClient.py"><span class="filename">listings/udp/MulticastClient.py</span></a></div></div>
 
253
 
 
254
    <p>
 
255
    This is a mirror implementation of a standard UDP client.  The only difference
 
256
    is that the destination IP is the multicast address.  This datagram will be
 
257
    distributed to every server listening on 224.0.0.1 and port 8005.  Note that
 
258
    the client port is specified as 0, as we have no need to keep track of what
 
259
    port the client is listening on.
 
260
    </p>
 
261
 
 
262
<h2>Acknowledgements<a name="auto4"/></h2>
 
263
 
 
264
<p>Thank you to all contributors to this document, including:</p>
 
265
 
 
266
<ul>
 
267
<li>Kyle Robertson, author of the explanation and examples of multicast</li>
 
268
</ul>
 
269
 
 
270
</div>
 
271
 
 
272
    <p><a href="index.html">Index</a></p>
 
273
    <span class="version">Version: 10.0.0</span>
 
274
  </body>
 
275
</html>
 
 
b'\\ No newline at end of file'