| 1 | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> |
| 2 | <html> |
| 3 | <head> |
| 4 | <link rel="STYLESHEET" href="lib.css" type='text/css' /> |
| 5 | <link rel="SHORTCUT ICON" href="../icons/pyfav.png" type="image/png" /> |
| 6 | <link rel='start' href='../index.html' title='Python Documentation Index' /> |
| 7 | <link rel="first" href="lib.html" title='Python Library Reference' /> |
| 8 | <link rel='contents' href='contents.html' title="Contents" /> |
| 9 | <link rel='index' href='genindex.html' title='Index' /> |
| 10 | <link rel='last' href='about.html' title='About this document...' /> |
| 11 | <link rel='help' href='about.html' title='About this document...' /> |
| 12 | <link rel="next" href="module-asynchat.html" /> |
| 13 | <link rel="prev" href="module-DocXMLRPCServer.html" /> |
| 14 | <link rel="parent" href="internet.html" /> |
| 15 | <link rel="next" href="asyncore-example.html" /> |
| 16 | <meta name='aesop' content='information' /> |
| 17 | <title>11.25 asyncore -- Asynchronous socket handler</title> |
| 18 | </head> |
| 19 | <body> |
| 20 | <DIV CLASS="navigation"> |
| 21 | <div id='top-navigation-panel' xml:id='top-navigation-panel'> |
| 22 | <table align="center" width="100%" cellpadding="0" cellspacing="2"> |
| 23 | <tr> |
| 24 | <td class='online-navigation'><a rel="prev" title="11.24.2 DocCGIXMLRPCRequestHandler" |
| 25 | href="node567.html"><img src='../icons/previous.png' |
| 26 | border='0' height='32' alt='Previous Page' width='32' /></A></td> |
| 27 | <td class='online-navigation'><a rel="parent" title="11. Internet Protocols and" |
| 28 | href="internet.html"><img src='../icons/up.png' |
| 29 | border='0' height='32' alt='Up One Level' width='32' /></A></td> |
| 30 | <td class='online-navigation'><a rel="next" title="11.25.1 asyncore Example basic" |
| 31 | href="asyncore-example.html"><img src='../icons/next.png' |
| 32 | border='0' height='32' alt='Next Page' width='32' /></A></td> |
| 33 | <td align="center" width="100%">Python Library Reference</td> |
| 34 | <td class='online-navigation'><a rel="contents" title="Table of Contents" |
| 35 | href="contents.html"><img src='../icons/contents.png' |
| 36 | border='0' height='32' alt='Contents' width='32' /></A></td> |
| 37 | <td class='online-navigation'><a href="modindex.html" title="Module Index"><img src='../icons/modules.png' |
| 38 | border='0' height='32' alt='Module Index' width='32' /></a></td> |
| 39 | <td class='online-navigation'><a rel="index" title="Index" |
| 40 | href="genindex.html"><img src='../icons/index.png' |
| 41 | border='0' height='32' alt='Index' width='32' /></A></td> |
| 42 | </tr></table> |
| 43 | <div class='online-navigation'> |
| 44 | <b class="navlabel">Previous:</b> |
| 45 | <a class="sectref" rel="prev" href="node567.html">11.24.2 DocCGIXMLRPCRequestHandler</A> |
| 46 | <b class="navlabel">Up:</b> |
| 47 | <a class="sectref" rel="parent" href="internet.html">11. Internet Protocols and</A> |
| 48 | <b class="navlabel">Next:</b> |
| 49 | <a class="sectref" rel="next" href="asyncore-example.html">11.25.1 asyncore Example basic</A> |
| 50 | </div> |
| 51 | <hr /></div> |
| 52 | </DIV> |
| 53 | <!--End of Navigation Panel--> |
| 54 | |
| 55 | <H1><A NAME="SECTION00132500000000000000000"> |
| 56 | 11.25 <tt class="module">asyncore</tt> -- |
| 57 | Asynchronous socket handler</A> |
| 58 | </H1> |
| 59 | |
| 60 | <P> |
| 61 | <A NAME="module-asyncore"></A> |
| 62 | |
| 63 | <P> |
| 64 | This module provides the basic infrastructure for writing asynchronous |
| 65 | socket service clients and servers. |
| 66 | |
| 67 | <P> |
| 68 | There are only two ways to have a program on a single processor do |
| 69 | ``more than one thing at a time.'' Multi-threaded programming is the |
| 70 | simplest and most popular way to do it, but there is another very |
| 71 | different technique, that lets you have nearly all the advantages of |
| 72 | multi-threading, without actually using multiple threads. It's really |
| 73 | only practical if your program is largely I/O bound. If your program |
| 74 | is processor bound, then pre-emptive scheduled threads are probably what |
| 75 | you really need. Network servers are rarely processor bound, however. |
| 76 | |
| 77 | <P> |
| 78 | If your operating system supports the <tt class="cfunction">select()</tt> system call |
| 79 | in its I/O library (and nearly all do), then you can use it to juggle |
| 80 | multiple communication channels at once; doing other work while your |
| 81 | I/O is taking place in the ``background.'' Although this strategy can |
| 82 | seem strange and complex, especially at first, it is in many ways |
| 83 | easier to understand and control than multi-threaded programming. |
| 84 | The <tt class="module">asyncore</tt> module solves many of the difficult problems for |
| 85 | you, making the task of building sophisticated high-performance |
| 86 | network servers and clients a snap. For ``conversational'' applications |
| 87 | and protocols the companion <tt class="module"><a href="module-asynchat.html">asynchat</a></tt> module is invaluable. |
| 88 | |
| 89 | <P> |
| 90 | The basic idea behind both modules is to create one or more network |
| 91 | <em>channels</em>, instances of class <tt class="class">asyncore.dispatcher</tt> and |
| 92 | <tt class="class">asynchat.async_chat</tt>. Creating the channels adds them to a global |
| 93 | map, used by the <tt class="function">loop()</tt> function if you do not provide it |
| 94 | with your own <var>map</var>. |
| 95 | |
| 96 | <P> |
| 97 | Once the initial channel(s) is(are) created, calling the <tt class="function">loop()</tt> |
| 98 | function activates channel service, which continues until the last |
| 99 | channel (including any that have been added to the map during asynchronous |
| 100 | service) is closed. |
| 101 | |
| 102 | <P> |
| 103 | <dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline"> |
| 104 | <td><nobr><b><tt id='l2h-3743' xml:id='l2h-3743' class="function">loop</tt></b>(</nobr></td> |
| 105 | <td><var></var><big>[</big><var>timeout</var><big>[</big><var>, use_poll</var><big>[</big><var>, |
| 106 | map</var><big>[</big><var>,count</var><big>]</big><var></var><big>]</big><var></var><big>]</big><var></var><big>]</big><var></var>)</td></tr></table></dt> |
| 107 | <dd> |
| 108 | Enter a polling loop that terminates after count passes or all open |
| 109 | channels have been closed. All arguments are optional. The <var>(</var>count) |
| 110 | parameter defaults to None, resulting in the loop terminating only |
| 111 | when all channels have been closed. The <var>timeout</var> argument sets the |
| 112 | timeout parameter for the appropriate <tt class="function">select()</tt> or |
| 113 | <tt class="function">poll()</tt> call, measured in seconds; the default is 30 seconds. |
| 114 | The <var>use_poll</var> parameter, if true, indicates that <tt class="function">poll()</tt> |
| 115 | should be used in preference to <tt class="function">select()</tt> (the default is |
| 116 | <code>False</code>). The <var>map</var> parameter is a dictionary whose items are |
| 117 | the channels to watch. As channels are closed they are deleted from their |
| 118 | map. If <var>map</var> is omitted, a global map is used (this map is updated |
| 119 | by the default class <tt class="method">__init__()</tt> - make sure you extend, rather |
| 120 | than override, <tt class="method">__init__()</tt> if you want to retain this behavior). |
| 121 | |
| 122 | <P> |
| 123 | Channels (instances of <tt class="class">asyncore.dispatcher</tt>, <tt class="class">asynchat.async_chat</tt> |
| 124 | and subclasses thereof) can freely be mixed in the map. |
| 125 | </dl> |
| 126 | |
| 127 | <P> |
| 128 | <dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline"> |
| 129 | <td><nobr><b><span class="typelabel">class</span> <tt id='l2h-3744' xml:id='l2h-3744' class="class">dispatcher</tt></b>(</nobr></td> |
| 130 | <td><var></var>)</td></tr></table></dt> |
| 131 | <dd> |
| 132 | The <tt class="class">dispatcher</tt> class is a thin wrapper around a low-level socket object. |
| 133 | To make it more useful, it has a few methods for event-handling which are called |
| 134 | from the asynchronous loop. |
| 135 | Otherwise, it can be treated as a normal non-blocking socket object. |
| 136 | |
| 137 | <P> |
| 138 | Two class attributes can be modified, to improve performance, |
| 139 | or possibly even to conserve memory. |
| 140 | |
| 141 | <P> |
| 142 | <dl><dt><b><tt id='l2h-3745' xml:id='l2h-3745'>ac_in_buffer_size</tt></b></dt> |
| 143 | <dd> |
| 144 | The asynchronous input buffer size (default <code>4096</code>). |
| 145 | </dd></dl> |
| 146 | |
| 147 | <P> |
| 148 | <dl><dt><b><tt id='l2h-3746' xml:id='l2h-3746'>ac_out_buffer_size</tt></b></dt> |
| 149 | <dd> |
| 150 | The asynchronous output buffer size (default <code>4096</code>). |
| 151 | </dd></dl> |
| 152 | |
| 153 | <P> |
| 154 | The firing of low-level events at certain times or in certain connection |
| 155 | states tells the asynchronous loop that certain higher-level events have |
| 156 | taken place. For example, if we have asked for a socket to connect to |
| 157 | another host, we know that the connection has been made when the socket |
| 158 | becomes writable for the first time (at this point you know that you may |
| 159 | write to it with the expectation of success). The implied higher-level |
| 160 | events are: |
| 161 | |
| 162 | <P> |
| 163 | <div class="center"><table class="realtable"> |
| 164 | <thead> |
| 165 | <tr> |
| 166 | <th class="left" >Event</th> |
| 167 | <th class="left" >Description</th> |
| 168 | </tr> |
| 169 | </thead> |
| 170 | <tbody> |
| 171 | <tr><td class="left" valign="baseline"><code>handle_connect()</code></td> |
| 172 | <td class="left" >Implied by the first write event</td></tr> |
| 173 | <tr><td class="left" valign="baseline"><code>handle_close()</code></td> |
| 174 | <td class="left" >Implied by a read event with no data available</td></tr> |
| 175 | <tr><td class="left" valign="baseline"><code>handle_accept()</code></td> |
| 176 | <td class="left" >Implied by a read event on a listening socket</td></tr></tbody> |
| 177 | </table></div> |
| 178 | |
| 179 | <P> |
| 180 | During asynchronous processing, each mapped channel's <tt class="method">readable()</tt> |
| 181 | and <tt class="method">writable()</tt> methods are used to determine whether the channel's |
| 182 | socket should be added to the list of channels <tt class="cfunction">select()</tt>ed or |
| 183 | <tt class="cfunction">poll()</tt>ed for read and write events. |
| 184 | |
| 185 | <P> |
| 186 | </dl> |
| 187 | |
| 188 | <P> |
| 189 | Thus, the set of channel events is larger than the basic socket events. |
| 190 | The full set of methods that can be overridden in your subclass follows: |
| 191 | |
| 192 | <P> |
| 193 | <dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline"> |
| 194 | <td><nobr><b><tt id='l2h-3747' xml:id='l2h-3747' class="method">handle_read</tt></b>(</nobr></td> |
| 195 | <td><var></var>)</td></tr></table></dt> |
| 196 | <dd> |
| 197 | Called when the asynchronous loop detects that a <tt class="method">read()</tt> |
| 198 | call on the channel's socket will succeed. |
| 199 | </dl> |
| 200 | |
| 201 | <P> |
| 202 | <dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline"> |
| 203 | <td><nobr><b><tt id='l2h-3748' xml:id='l2h-3748' class="method">handle_write</tt></b>(</nobr></td> |
| 204 | <td><var></var>)</td></tr></table></dt> |
| 205 | <dd> |
| 206 | Called when the asynchronous loop detects that a writable socket |
| 207 | can be written. |
| 208 | Often this method will implement the necessary buffering for |
| 209 | performance. For example: |
| 210 | |
| 211 | <P> |
| 212 | <div class="verbatim"><pre> |
| 213 | def handle_write(self): |
| 214 | sent = self.send(self.buffer) |
| 215 | self.buffer = self.buffer[sent:] |
| 216 | </pre></div> |
| 217 | </dl> |
| 218 | |
| 219 | <P> |
| 220 | <dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline"> |
| 221 | <td><nobr><b><tt id='l2h-3749' xml:id='l2h-3749' class="method">handle_expt</tt></b>(</nobr></td> |
| 222 | <td><var></var>)</td></tr></table></dt> |
| 223 | <dd> |
| 224 | Called when there is out of band (OOB) data for a socket |
| 225 | connection. This will almost never happen, as OOB is |
| 226 | tenuously supported and rarely used. |
| 227 | </dl> |
| 228 | |
| 229 | <P> |
| 230 | <dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline"> |
| 231 | <td><nobr><b><tt id='l2h-3750' xml:id='l2h-3750' class="method">handle_connect</tt></b>(</nobr></td> |
| 232 | <td><var></var>)</td></tr></table></dt> |
| 233 | <dd> |
| 234 | Called when the active opener's socket actually makes a connection. |
| 235 | Might send a ``welcome'' banner, or initiate a protocol |
| 236 | negotiation with the remote endpoint, for example. |
| 237 | </dl> |
| 238 | |
| 239 | <P> |
| 240 | <dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline"> |
| 241 | <td><nobr><b><tt id='l2h-3751' xml:id='l2h-3751' class="method">handle_close</tt></b>(</nobr></td> |
| 242 | <td><var></var>)</td></tr></table></dt> |
| 243 | <dd> |
| 244 | Called when the socket is closed. |
| 245 | </dl> |
| 246 | |
| 247 | <P> |
| 248 | <dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline"> |
| 249 | <td><nobr><b><tt id='l2h-3752' xml:id='l2h-3752' class="method">handle_error</tt></b>(</nobr></td> |
| 250 | <td><var></var>)</td></tr></table></dt> |
| 251 | <dd> |
| 252 | Called when an exception is raised and not otherwise handled. The default |
| 253 | version prints a condensed traceback. |
| 254 | </dl> |
| 255 | |
| 256 | <P> |
| 257 | <dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline"> |
| 258 | <td><nobr><b><tt id='l2h-3753' xml:id='l2h-3753' class="method">handle_accept</tt></b>(</nobr></td> |
| 259 | <td><var></var>)</td></tr></table></dt> |
| 260 | <dd> |
| 261 | Called on listening channels (passive openers) when a |
| 262 | connection can be established with a new remote endpoint that |
| 263 | has issued a <tt class="method">connect()</tt> call for the local endpoint. |
| 264 | </dl> |
| 265 | |
| 266 | <P> |
| 267 | <dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline"> |
| 268 | <td><nobr><b><tt id='l2h-3754' xml:id='l2h-3754' class="method">readable</tt></b>(</nobr></td> |
| 269 | <td><var></var>)</td></tr></table></dt> |
| 270 | <dd> |
| 271 | Called each time around the asynchronous loop to determine whether a |
| 272 | channel's socket should be added to the list on which read events can |
| 273 | occur. The default method simply returns <code>True</code>, |
| 274 | indicating that by default, all channels will be interested in |
| 275 | read events. |
| 276 | </dl> |
| 277 | |
| 278 | <P> |
| 279 | <dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline"> |
| 280 | <td><nobr><b><tt id='l2h-3755' xml:id='l2h-3755' class="method">writable</tt></b>(</nobr></td> |
| 281 | <td><var></var>)</td></tr></table></dt> |
| 282 | <dd> |
| 283 | Called each time around the asynchronous loop to determine whether a |
| 284 | channel's socket should be added to the list on which write events can |
| 285 | occur. The default method simply returns <code>True</code>, |
| 286 | indicating that by default, all channels will be interested in |
| 287 | write events. |
| 288 | </dl> |
| 289 | |
| 290 | <P> |
| 291 | In addition, each channel delegates or extends many of the socket methods. |
| 292 | Most of these are nearly identical to their socket partners. |
| 293 | |
| 294 | <P> |
| 295 | <dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline"> |
| 296 | <td><nobr><b><tt id='l2h-3756' xml:id='l2h-3756' class="method">create_socket</tt></b>(</nobr></td> |
| 297 | <td><var>family, type</var>)</td></tr></table></dt> |
| 298 | <dd> |
| 299 | This is identical to the creation of a normal socket, and |
| 300 | will use the same options for creation. Refer to the |
| 301 | <tt class="module"><a href="module-socket.html">socket</a></tt> documentation for information on creating |
| 302 | sockets. |
| 303 | </dl> |
| 304 | |
| 305 | <P> |
| 306 | <dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline"> |
| 307 | <td><nobr><b><tt id='l2h-3757' xml:id='l2h-3757' class="method">connect</tt></b>(</nobr></td> |
| 308 | <td><var>address</var>)</td></tr></table></dt> |
| 309 | <dd> |
| 310 | As with the normal socket object, <var>address</var> is a |
| 311 | tuple with the first element the host to connect to, and the |
| 312 | second the port number. |
| 313 | </dl> |
| 314 | |
| 315 | <P> |
| 316 | <dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline"> |
| 317 | <td><nobr><b><tt id='l2h-3758' xml:id='l2h-3758' class="method">send</tt></b>(</nobr></td> |
| 318 | <td><var>data</var>)</td></tr></table></dt> |
| 319 | <dd> |
| 320 | Send <var>data</var> to the remote end-point of the socket. |
| 321 | </dl> |
| 322 | |
| 323 | <P> |
| 324 | <dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline"> |
| 325 | <td><nobr><b><tt id='l2h-3759' xml:id='l2h-3759' class="method">recv</tt></b>(</nobr></td> |
| 326 | <td><var>buffer_size</var>)</td></tr></table></dt> |
| 327 | <dd> |
| 328 | Read at most <var>buffer_size</var> bytes from the socket's remote end-point. |
| 329 | An empty string implies that the channel has been closed from the other |
| 330 | end. |
| 331 | </dl> |
| 332 | |
| 333 | <P> |
| 334 | <dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline"> |
| 335 | <td><nobr><b><tt id='l2h-3760' xml:id='l2h-3760' class="method">listen</tt></b>(</nobr></td> |
| 336 | <td><var>backlog</var>)</td></tr></table></dt> |
| 337 | <dd> |
| 338 | Listen for connections made to the socket. The <var>backlog</var> |
| 339 | argument specifies the maximum number of queued connections |
| 340 | and should be at least 1; the maximum value is |
| 341 | system-dependent (usually 5). |
| 342 | </dl> |
| 343 | |
| 344 | <P> |
| 345 | <dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline"> |
| 346 | <td><nobr><b><tt id='l2h-3761' xml:id='l2h-3761' class="method">bind</tt></b>(</nobr></td> |
| 347 | <td><var>address</var>)</td></tr></table></dt> |
| 348 | <dd> |
| 349 | Bind the socket to <var>address</var>. The socket must not already |
| 350 | be bound. (The format of <var>address</var> depends on the address |
| 351 | family -- see above.) |
| 352 | </dl> |
| 353 | |
| 354 | <P> |
| 355 | <dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline"> |
| 356 | <td><nobr><b><tt id='l2h-3762' xml:id='l2h-3762' class="method">accept</tt></b>(</nobr></td> |
| 357 | <td><var></var>)</td></tr></table></dt> |
| 358 | <dd> |
| 359 | Accept a connection. The socket must be bound to an address |
| 360 | and listening for connections. The return value is a pair |
| 361 | <code>(<var>conn</var>, <var>address</var>)</code> where <var>conn</var> is a |
| 362 | <em>new</em> socket object usable to send and receive data on |
| 363 | the connection, and <var>address</var> is the address bound to the |
| 364 | socket on the other end of the connection. |
| 365 | </dl> |
| 366 | |
| 367 | <P> |
| 368 | <dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline"> |
| 369 | <td><nobr><b><tt id='l2h-3763' xml:id='l2h-3763' class="method">close</tt></b>(</nobr></td> |
| 370 | <td><var></var>)</td></tr></table></dt> |
| 371 | <dd> |
| 372 | Close the socket. All future operations on the socket object |
| 373 | will fail. The remote end-point will receive no more data (after |
| 374 | queued data is flushed). Sockets are automatically closed |
| 375 | when they are garbage-collected. |
| 376 | </dl> |
| 377 | |
| 378 | <P> |
| 379 | |
| 380 | <p><br /></p><hr class='online-navigation' /> |
| 381 | <div class='online-navigation'> |
| 382 | <!--Table of Child-Links--> |
| 383 | <A NAME="CHILD_LINKS"><STRONG>Subsections</STRONG></a> |
| 384 | |
| 385 | <UL CLASS="ChildLinks"> |
| 386 | <LI><A href="asyncore-example.html">11.25.1 asyncore Example basic HTTP client</a> |
| 387 | </ul> |
| 388 | <!--End of Table of Child-Links--> |
| 389 | </div> |
| 390 | |
| 391 | <DIV CLASS="navigation"> |
| 392 | <div class='online-navigation'> |
| 393 | <p></p><hr /> |
| 394 | <table align="center" width="100%" cellpadding="0" cellspacing="2"> |
| 395 | <tr> |
| 396 | <td class='online-navigation'><a rel="prev" title="11.24.2 DocCGIXMLRPCRequestHandler" |
| 397 | href="node567.html"><img src='../icons/previous.png' |
| 398 | border='0' height='32' alt='Previous Page' width='32' /></A></td> |
| 399 | <td class='online-navigation'><a rel="parent" title="11. Internet Protocols and" |
| 400 | href="internet.html"><img src='../icons/up.png' |
| 401 | border='0' height='32' alt='Up One Level' width='32' /></A></td> |
| 402 | <td class='online-navigation'><a rel="next" title="11.25.1 asyncore Example basic" |
| 403 | href="asyncore-example.html"><img src='../icons/next.png' |
| 404 | border='0' height='32' alt='Next Page' width='32' /></A></td> |
| 405 | <td align="center" width="100%">Python Library Reference</td> |
| 406 | <td class='online-navigation'><a rel="contents" title="Table of Contents" |
| 407 | href="contents.html"><img src='../icons/contents.png' |
| 408 | border='0' height='32' alt='Contents' width='32' /></A></td> |
| 409 | <td class='online-navigation'><a href="modindex.html" title="Module Index"><img src='../icons/modules.png' |
| 410 | border='0' height='32' alt='Module Index' width='32' /></a></td> |
| 411 | <td class='online-navigation'><a rel="index" title="Index" |
| 412 | href="genindex.html"><img src='../icons/index.png' |
| 413 | border='0' height='32' alt='Index' width='32' /></A></td> |
| 414 | </tr></table> |
| 415 | <div class='online-navigation'> |
| 416 | <b class="navlabel">Previous:</b> |
| 417 | <a class="sectref" rel="prev" href="node567.html">11.24.2 DocCGIXMLRPCRequestHandler</A> |
| 418 | <b class="navlabel">Up:</b> |
| 419 | <a class="sectref" rel="parent" href="internet.html">11. Internet Protocols and</A> |
| 420 | <b class="navlabel">Next:</b> |
| 421 | <a class="sectref" rel="next" href="asyncore-example.html">11.25.1 asyncore Example basic</A> |
| 422 | </div> |
| 423 | </div> |
| 424 | <hr /> |
| 425 | <span class="release-info">Release 2.4.2, documentation updated on 28 September 2005.</span> |
| 426 | </DIV> |
| 427 | <!--End of Navigation Panel--> |
| 428 | <ADDRESS> |
| 429 | See <i><a href="about.html">About this document...</a></i> for information on suggesting changes. |
| 430 | </ADDRESS> |
| 431 | </BODY> |
| 432 | </HTML> |