5 -----------------------------
6 Asynchronous socket handler
7 -----------------------------
10 Synopsis: A base class for developing asynchronous socket
13 Module-Author: Sam Rushing <rushing@nightmare.com>
14 Author: Christopher Petrilli <petrilli@amber.org>
15 Author: Steve Holden <sholden@holdenweb.com>
17 .. Type: ... builtin, standard, various others: any specific usages required?
19 .. Heavily adapted from original documentation by Sam Rushing.
21 .. ............................................
22 .. This is the (first) RFC822-reader strawman
23 .. ............................................
24 .. Presumes a custom reader appropriate to docpy
25 .. RFC822 continuation IS allowed (see Synopsis)
26 .. Needtocheck: RFC822-readers and multiple entities? (Author lines)
27 .. Dunno about implication of \section in the original
28 .. Dunno about comments (#?); "Credit: Sam Rushing?"
29 .. Note in passing: names of new roles and directives made similar to
30 .. the existing docpy macros on purpose (for existing corpus & community)
32 .. Markups needed, used, and existing in rst:
35 .. Markups needed, used, and modified by this strawman:
38 .. Roles needed below by this strawman:
47 .. Directives needed below by this strawman:
49 .. need to parse for optional argumnents shown as [...]
53 .. TBS - formals, e.g., funcdesc - several alternatives proposed
54 .. below (see funcdesc) in this draft
55 .. the one shown first seems on track for consensus 04.3.20
56 .. (the directive will parse brackets, etc. - easier to use!)
58 This module provides the basic infrastructure for writing asynchronous
59 socket service clients and servers.
61 There are only two ways to have a program on a single processor do
62 "more than one thing at a time." Multi-threaded programming is the
63 simplest and most popular way to do it, but there is another very
64 different technique, that lets you have nearly all the advantages of
65 multi-threading, without actually using multiple threads. It's really
66 only practical if your program is largely I/O bound. If your program
67 is processor bound, then pre-emptive scheduled threads are probably what
68 you really need. Network servers are rarely processor bound, however.
70 If your operating system supports the :cfunction:`select()` system call
71 in its I/O library (and nearly all do), then you can use it to juggle
72 multiple communication channels at once; doing other work while your
73 I/O is taking place in the "background." Although this strategy can
74 seem strange and complex, especially at first, it is in many ways
75 easier to understand and control than multi-threaded programming.
76 The :module:`asyncore` module solves many of the difficult problems for
77 you, making the task of building sophisticated high-performance
78 network servers and clients a snap. For "conversational" applications
79 and protocols the companion :refmodule:`asynchat` module is invaluable.
81 The basic idea behind both modules is to create one or more network
82 *channels*, instances of class :class:`asyncore.dispatcher` and
83 :class:`asynchat.async_chat`. Creating the channels adds them to a global
84 map, used by the :function:`loop()` function if you do not provide it
85 with your own :var:`map`.
87 Once the initial channel(s) is(are) created, calling the :function:`loop()`
88 function activates channel service, which continues until the last
89 channel (including any that have been added to the map during asynchronous
92 .. funcdesc:: loop([timeout [, use_poll [, map]]])
94 Enter a polling loop that only terminates after all open channels
95 have been closed. All arguments are optional. The :var:`timeout`
96 argument sets the timeout parameter for the appropriate
97 :function:`select()` or :function:`poll()` call, measured in seconds;
98 the default is 30 seconds. The :var:`use_poll` parameter, if true,
99 indicates that :function:`poll()` should be used in preference to
100 :function:`select()` (the default is ``False``). The :var:`map` parameter
101 is a dictionary whose items are the channels to watch. As channels
102 are closed they are deleted from their map. If :var:`map` is
103 omitted, a global map is used (this map is updated by the default
104 class :method:`__init__()`
105 -- make sure you extend, rather than override, :method:`__init__()`
106 if you want to retain this behavior).
108 Channels (instances of :class:`asyncore.dispatcher`, :class:`asynchat.async_chat`
109 and subclasses thereof) can freely be mixed in the map.
111 .. classdesc:: dispatcher()
113 The :class:`dispatcher` class is a thin wrapper around a low-level socket object.
114 To make it more useful, it has a few methods for event-handling which are called
115 from the asynchronous loop.
116 Otherwise, it can be treated as a normal non-blocking socket object.
118 Two class attributes can be modified, to improve performance,
119 or possibly even to conserve memory.
121 .. datadesc:: ac_in_buffer_size
123 The asynchronous input buffer size (default ``4096``).
125 .. datadesc:: ac_out_buffer_size
127 The asynchronous output buffer size (default ``4096``).
129 The firing of low-level events at certain times or in certain connection
130 states tells the asynchronous loop that certain higher-level events have
131 taken place. For example, if we have asked for a socket to connect to
132 another host, we know that the connection has been made when the socket
133 becomes writable for the first time (at this point you know that you may
134 write to it with the expectation of success). The implied higher-level
137 ===================== ===============================================
138 ``Event`` Description
139 --------------------- -----------------------------------------------
140 ``handle_connect()`` Implied by the first write event
141 ``handle_close()`` Implied by a read event with no data available
142 ``handle_accept()`` Implied by a read event on a listening socket
143 ===================== ===============================================
146 During asynchronous processing, each mapped channel's :method:`readable()`
147 and :method:`writable()` methods are used to determine whether the channel's
148 socket should be added to the list of channels :cfunction:`select()`\ ed or
149 :cfunction:`poll()`\ ed for read and write events.
151 Thus, the set of channel events is larger than the basic socket events.
152 The full set of methods that can be overridden in your subclass follows:
154 .. methoddesc:: handle_read()
156 Called when the asynchronous loop detects that a :method:`read()`
157 call on the channel's socket will succeed.
159 .. methoddesc:: handle_write()
161 Called when the asynchronous loop detects that a writable socket
163 Often this method will implement the necessary buffering for
164 performance. For example::
167 def handle_write(self):
168 sent = self.send(self.buffer)
169 self.buffer = self.buffer[sent:]
171 .. methoddesc:: handle_expt()
173 Called when there is out of band (OOB) data for a socket
174 connection. This will almost never happen, as OOB is
175 tenuously supported and rarely used.
177 .. methoddesc:: handle_connect()
179 Called when the active opener's socket actually makes a connection.
180 Might send a "welcome" banner, or initiate a protocol
181 negotiation with the remote endpoint, for example.
183 .. methoddesc:: handle_close()
185 Called when the socket is closed.
187 .. methoddesc:: handle_error()
189 Called when an exception is raised and not otherwise handled. The default
190 version prints a condensed traceback.
192 .. methoddesc:: handle_accept()
194 Called on listening channels (passive openers) when a
195 connection can be established with a new remote endpoint that
196 has issued a :method:`connect()` call for the local endpoint.
198 .. methoddesc:: readable()
200 Called each time around the asynchronous loop to determine whether a
201 channel's socket should be added to the list on which read events can
202 occur. The default method simply returns ``True``,
203 indicating that by default, all channels will be interested in
206 .. methoddesc:: writable()
208 Called each time around the asynchronous loop to determine whether a
209 channel's socket should be added to the list on which write events can
210 occur. The default method simply returns ``True``,
211 indicating that by default, all channels will be interested in
214 In addition, each channel delegates or extends many of the socket methods.
215 Most of these are nearly identical to their socket partners.
217 .. methoddesc:: create_socket(family, type)
219 This is identical to the creation of a normal socket, and
220 will use the same options for creation. Refer to the
221 :refmodule:`socket` documentation for information on creating
224 .. methoddesc:: connect(address)
226 As with the normal socket object, :var:`address` is a
227 tuple with the first element the host to connect to, and the
228 second the port number.
230 .. methoddesc:: send(data)
232 Send :var:`data` to the remote end-point of the socket.
234 .. methoddesc:: recv(buffer_size)
236 Read at most :var:`buffer_size` bytes from the socket's remote end-point.
237 An empty string implies that the channel has been closed from the other
240 .. methoddesc:: listen(backlog)
242 Listen for connections made to the socket. The :var:`backlog`
243 argument specifies the maximum number of queued connections
244 and should be at least 1; the maximum value is
245 system-dependent (usually 5).
247 .. methoddesc:: bind(address)
249 Bind the socket to :var:`address`. The socket must not already
250 be bound. (The format of :var:`address` depends on the address
251 family --- see above.)
253 .. methoddesc:: accept()
255 Accept a connection. The socket must be bound to an address
256 and listening for connections. The return value is a pair
257 ``(conn , address)`` where :var:`conn` is a
258 *new* socket object usable to send and receive data on
259 the connection, and :var:`address` is the address bound to the
260 socket on the other end of the connection.
262 .. methoddesc:: close()
264 Close the socket. All future operations on the socket object
265 will fail. The remote end-point will receive no more data (after
266 queued data is flushed). Sockets are automatically closed
267 when they are garbage-collected.
270 asyncore Example basic HTTP client :label:`asyncore-example`
271 ------------------------------------------------------------
272 As a basic example, below is a very basic HTTP client that uses the
273 :class:`dispatcher` class to implement its socket handling::
275 class http_client(asyncore.dispatcher):
276 def __init__(self, host,path):
277 asyncore.dispatcher.__init__(self)
279 self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
280 self.connect( (host, 80) )
281 self.buffer = 'GET %s HTTP/1.0\r\n\r\n' % self.path
283 def handle_connect(self):
286 def handle_read(self):
287 data = self.recv(8192)
291 return (len(self.buffer) > 0)
293 def handle_write(self):
294 sent = self.send(self.buffer)
295 self.buffer = self.buffer[sent:]