Initial import to Tizen
[profile/ivi/python-twisted.git] / doc / core / howto / udp.html
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></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 on
17     the network. In addition, datagrams may arrive in any order, never arrive at
18     all, or be duplicated in transit.</p>
19
20     <p>Since there are no connections, we only use a single object, a protocol,
21     for each UDP socket. We then use the reactor to connect this protocol to a
22     UDP transport, using the
23     <code class="API"><a href="http://twistedmatrix.com/documents/12.1.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>The class where you actually implement the protocol parsing and handling
29     will usually be descended
30     from <code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.internet.protocol.DatagramProtocol.html" title="twisted.internet.protocol.DatagramProtocol">twisted.internet.protocol.DatagramProtocol</a></code> or
31     from one of its convenience children. The <code>DatagramProtocol</code>
32     class receives datagrams and can send them out over the network. Received
33     datagrams include the address they were sent from. When sending datagrams
34     the destination address must be specified.</p>
35
36     <p>Here is a simple example:</p>
37     <pre class="python"><p class="py-linenumber"> 1
38  2
39  3
40  4
41  5
42  6
43  7
44  8
45  9
46 10
47 11
48 </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>
49 <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>
50
51 <span class="py-src-keyword">class</span> <span class="py-src-identifier">Echo</span>(<span class="py-src-parameter">DatagramProtocol</span>):
52
53     <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>)):
54         <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>)
55         <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>))
56
57 <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>())
58 <span class="py-src-variable">reactor</span>.<span class="py-src-variable">run</span>()
59 </pre>
60
61     <p>As you can see, the protocol is registered with the reactor. This means
62     it may be persisted if it's added to an application, and thus it has
63     <code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.internet.protocol.AbstractDatagramProtocol.startProtocol.html" title="twisted.internet.protocol.AbstractDatagramProtocol.startProtocol">startProtocol</a></code>
64     and <code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.internet.protocol.AbstractDatagramProtocol.stopProtocol.html" title="twisted.internet.protocol.AbstractDatagramProtocol.stopProtocol">stopProtocol</a></code>
65     methods that will get called when the protocol is connected and disconnected
66     from a UDP socket.</p>
67
68     <p>The protocol's <code class="python">transport</code> attribute will
69     implement the <code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.internet.interfaces.IUDPTransport.html" title="twisted.internet.interfaces.IUDPTransport">twisted.internet.interfaces.IUDPTransport</a></code> interface.
70     Notice that the <code class="python">host</code> argument should be an
71     IP address, 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/12.1.0/api/twisted.internet.interfaces.IReactorCore.resolve.html" title="twisted.internet.interfaces.IReactorCore.resolve">twisted.internet.interfaces.IReactorCore.resolve</a></code>).</p>
72
73
74     <h2>Connected UDP<a name="auto2"/></h2>
75
76     <p>A connected UDP socket is slightly different from a standard one - it
77     can only send and receive datagrams to/from a single address, but this
78     does not in any way imply a connection. Datagrams may still arrive in any
79     order, and the port on the other side may have no one listening. The
80     benefit of the connected UDP socket is that it it <strong>may</strong>
81     provide notification of undelivered packages. This depends on many
82     factors, almost all of which are out of the control of the application,
83     but it still presents certain benefits which occasionally make it
84     useful.</p>
85
86     <p>Unlike a regular UDP protocol, we do not need to specify where to send
87     datagrams and are not told where they came from since they can only come
88     from the address to which the socket is 'connected'.</p>
89
90     <pre class="python"><p class="py-linenumber"> 1
91  2
92  3
93  4
94  5
95  6
96  7
97  8
98  9
99 10
100 11
101 12
102 13
103 14
104 15
105 16
106 17
107 18
108 19
109 20
110 21
111 22
112 23
113 24
114 </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>
115 <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>
116
117 <span class="py-src-keyword">class</span> <span class="py-src-identifier">Helloer</span>(<span class="py-src-parameter">DatagramProtocol</span>):
118
119     <span class="py-src-keyword">def</span> <span class="py-src-identifier">startProtocol</span>(<span class="py-src-parameter">self</span>):
120         <span class="py-src-variable">host</span> = <span class="py-src-string">&quot;192.168.1.1&quot;</span>
121         <span class="py-src-variable">port</span> = <span class="py-src-number">1234</span>
122
123         <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-variable">host</span>, <span class="py-src-variable">port</span>)
124         <span class="py-src-keyword">print</span> <span class="py-src-string">&quot;now we can only send to host %s port %d&quot;</span> % (<span class="py-src-variable">host</span>, <span class="py-src-variable">port</span>)
125         <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>
126
127     <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>)):
128         <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>)
129
130     <span class="py-src-comment"># Possibly invoked if there is no server listening on the</span>
131     <span class="py-src-comment"># address to which we are sending.</span>
132     <span class="py-src-keyword">def</span> <span class="py-src-identifier">connectionRefused</span>(<span class="py-src-parameter">self</span>):
133         <span class="py-src-keyword">print</span> <span class="py-src-string">&quot;No one listening&quot;</span>
134
135 <span class="py-src-comment"># 0 means any port, we don't care in this case</span>
136 <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>())
137 <span class="py-src-variable">reactor</span>.<span class="py-src-variable">run</span>()
138 </pre>
139
140     <p>Note that <code class="python">connect()</code>,
141     like <code class="python">write()</code> will only accept IP addresses, not
142     unresolved hostnames. To obtain the IP of a hostname
143     use <code class="python">reactor.resolve()</code>, e.g.:</p>
144
145   <pre class="python"><p class="py-linenumber">1
146 2
147 3
148 4
149 5
150 6
151 7
152 8
153 </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>
154
155 <span class="py-src-keyword">def</span> <span class="py-src-identifier">gotIP</span>(<span class="py-src-parameter">ip</span>):
156     <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>
157     <span class="py-src-variable">reactor</span>.<span class="py-src-variable">callLater</span>(<span class="py-src-number">3</span>, <span class="py-src-variable">reactor</span>.<span class="py-src-variable">stop</span>)
158
159 <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>)
160 <span class="py-src-variable">reactor</span>.<span class="py-src-variable">run</span>()
161 </pre>
162
163     <p>Connecting to a new address after a previous connection or making a
164     connected port unconnected are not currently supported, but likely will be
165     in the future.</p>
166
167     <h2>Multicast UDP<a name="auto3"/></h2>
168
169     <p>Multicast allows a process to contact multiple hosts with a single
170     packet, without knowing the specific IP address of any of the hosts. This
171     is in contrast to normal, or unicast, UDP, where each datagram has a single
172     IP as its destination. Multicast datagrams are sent to special multicast
173     group addresses (in the IPv4 range 224.0.0.0 to 239.255.255.255), along with
174     a corresponding port. In order to receive multicast datagrams, you must
175     join that specific group address. However, any UDP socket can send to
176     multicast addresses.</p>
177
178     <div class="py-listing"><pre><p class="py-linenumber"> 1
179  2
180  3
181  4
182  5
183  6
184  7
185  8
186  9
187 10
188 11
189 12
190 13
191 14
192 15
193 16
194 17
195 18
196 19
197 20
198 21
199 22
200 23
201 24
202 25
203 26
204 27
205 28
206 </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>
207 <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>
208
209
210 <span class="py-src-keyword">class</span> <span class="py-src-identifier">MulticastPingPong</span>(<span class="py-src-parameter">DatagramProtocol</span>):
211
212     <span class="py-src-keyword">def</span> <span class="py-src-identifier">startProtocol</span>(<span class="py-src-parameter">self</span>):
213         <span class="py-src-string">&quot;&quot;&quot;
214         Called after protocol has started listening.
215         &quot;&quot;&quot;</span>
216         <span class="py-src-comment"># Set the TTL&gt;1 so multicast will cross router hops:</span>
217         <span class="py-src-variable">self</span>.<span class="py-src-variable">transport</span>.<span class="py-src-variable">setTTL</span>(<span class="py-src-number">5</span>)
218         <span class="py-src-comment"># Join a specific multicast group:</span>
219         <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">&quot;228.0.0.5&quot;</span>)
220
221     <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>):
222         <span class="py-src-keyword">print</span> <span class="py-src-string">&quot;Datagram %s received from %s&quot;</span> % (<span class="py-src-variable">repr</span>(<span class="py-src-variable">datagram</span>), <span class="py-src-variable">repr</span>(<span class="py-src-variable">address</span>))
223         <span class="py-src-keyword">if</span> <span class="py-src-variable">datagram</span> == <span class="py-src-string">&quot;Client: Ping&quot;</span>:
224             <span class="py-src-comment"># Rather than replying to the group multicast address, we send the</span>
225             <span class="py-src-comment"># reply directly (unicast) to the originating port:</span>
226             <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;Server: Pong&quot;</span>, <span class="py-src-variable">address</span>)
227
228
229 <span class="py-src-comment"># We use listenMultiple=True so that we can run MulticastServer.py and</span>
230 <span class="py-src-comment"># MulticastClient.py on same machine:</span>
231 <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">MulticastPingPong</span>(),
232                         <span class="py-src-variable">listenMultiple</span>=<span class="py-src-variable">True</span>)
233 <span class="py-src-variable">reactor</span>.<span class="py-src-variable">run</span>()
234 </pre><div class="caption">Source listing - <a href="listings/udp/MulticastServer.py"><span class="filename">listings/udp/MulticastServer.py</span></a></div></div>
235
236     <p>As with UDP, with multicast there is no server/client differentiation
237     at the protocol level. Our server example is very simple and closely
238     resembles a normal <code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.internet.interfaces.IReactorUDP.listenUDP.html" title="twisted.internet.interfaces.IReactorUDP.listenUDP">listenUDP</a></code>
239     protocol implementation.  The main difference is that instead
240     of <code>listenUDP</code>, <code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.internet.interfaces.IReactorMulticast.listenMulticast.html" title="twisted.internet.interfaces.IReactorMulticast.listenMulticast">listenMulticast</a></code>
241     is called with the port number. The server calls <code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.internet.interfaces.IMulticastTransport.joinGroup.html" title="twisted.internet.interfaces.IMulticastTransport.joinGroup">joinGroup</a></code> to
242     join a multicast group. A <code class="python">DatagramProtocol</code>
243     that is listening with multicast and has joined a group can receive
244     multicast datagrams, but also unicast datagrams sent directly to its
245     address. The server in the example above sends such a unicast message in
246     reply to the multicast message it receives from the client.
247     </p>
248
249     <div class="py-listing"><pre><p class="py-linenumber"> 1
250  2
251  3
252  4
253  5
254  6
255  7
256  8
257  9
258 10
259 11
260 12
261 13
262 14
263 15
264 16
265 17
266 18
267 19
268 </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>
269 <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>
270
271
272 <span class="py-src-keyword">class</span> <span class="py-src-identifier">MulticastPingClient</span>(<span class="py-src-parameter">DatagramProtocol</span>):
273
274     <span class="py-src-keyword">def</span> <span class="py-src-identifier">startProtocol</span>(<span class="py-src-parameter">self</span>):
275         <span class="py-src-comment"># Join the multicast address, so we can receive replies:</span>
276         <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">&quot;228.0.0.5&quot;</span>)
277         <span class="py-src-comment"># Send to 228.0.0.5:8005 - all listeners on the multicast address</span>
278         <span class="py-src-comment"># (including us) will receive this message.</span>
279         <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">'Client: Ping'</span>, (<span class="py-src-string">&quot;228.0.0.5&quot;</span>, <span class="py-src-number">8005</span>))
280
281     <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>):
282         <span class="py-src-keyword">print</span> <span class="py-src-string">&quot;Datagram %s received from %s&quot;</span> % (<span class="py-src-variable">repr</span>(<span class="py-src-variable">datagram</span>), <span class="py-src-variable">repr</span>(<span class="py-src-variable">address</span>))
283
284
285 <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">MulticastPingClient</span>(), <span class="py-src-variable">listenMultiple</span>=<span class="py-src-variable">True</span>)
286 <span class="py-src-variable">reactor</span>.<span class="py-src-variable">run</span>()
287 </pre><div class="caption">Source listing - <a href="listings/udp/MulticastClient.py"><span class="filename">listings/udp/MulticastClient.py</span></a></div></div>
288
289     <p>Note that a multicast socket will have a default TTL (time to live) of
290     1. That is, datagrams won't traverse more than one router hop, unless a
291     higher TTL is set with
292      <code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.internet.interfaces.IMulticastTransport.setTTL.html" title="twisted.internet.interfaces.IMulticastTransport.setTTL">setTTL</a></code>. Other
293     functionality provided by the multicast transport
294     includes <code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.internet.interfaces.IMulticastTransport.setOutgoingInterface.html" title="twisted.internet.interfaces.IMulticastTransport.setOutgoingInterface">setOutgoingInterface</a></code>
295     and <code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.internet.interfaces.IMulticastTransport.setLoopbackMode.html" title="twisted.internet.interfaces.IMulticastTransport.setLoopbackMode">setLoopbackMode</a></code>
296     -- see <code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.internet.interfaces.IMulticastTransport.html" title="twisted.internet.interfaces.IMulticastTransport">IMulticastTransport</a></code> for more
297     information.</p>
298
299 </div>
300
301     <p><a href="index.html">Index</a></p>
302     <span class="version">Version: 12.1.0</span>
303   </body>
304 </html>