17db96d56Sopenharmony_ci:mod:`asyncore` --- Asynchronous socket handler 27db96d56Sopenharmony_ci=============================================== 37db96d56Sopenharmony_ci 47db96d56Sopenharmony_ci.. module:: asyncore 57db96d56Sopenharmony_ci :synopsis: A base class for developing asynchronous socket handling 67db96d56Sopenharmony_ci services. 77db96d56Sopenharmony_ci :deprecated: 87db96d56Sopenharmony_ci 97db96d56Sopenharmony_ci.. moduleauthor:: Sam Rushing <rushing@nightmare.com> 107db96d56Sopenharmony_ci.. sectionauthor:: Christopher Petrilli <petrilli@amber.org> 117db96d56Sopenharmony_ci.. sectionauthor:: Steve Holden <sholden@holdenweb.com> 127db96d56Sopenharmony_ci.. heavily adapted from original documentation by Sam Rushing 137db96d56Sopenharmony_ci 147db96d56Sopenharmony_ci**Source code:** :source:`Lib/asyncore.py` 157db96d56Sopenharmony_ci 167db96d56Sopenharmony_ci.. deprecated-removed:: 3.6 3.12 177db96d56Sopenharmony_ci The :mod:`asyncore` module is deprecated 187db96d56Sopenharmony_ci (see :pep:`PEP 594 <594#asyncore>` for details). 197db96d56Sopenharmony_ci Please use :mod:`asyncio` instead. 207db96d56Sopenharmony_ci 217db96d56Sopenharmony_ci-------------- 227db96d56Sopenharmony_ci 237db96d56Sopenharmony_ci.. note:: 247db96d56Sopenharmony_ci 257db96d56Sopenharmony_ci This module exists for backwards compatibility only. For new code we 267db96d56Sopenharmony_ci recommend using :mod:`asyncio`. 277db96d56Sopenharmony_ci 287db96d56Sopenharmony_ciThis module provides the basic infrastructure for writing asynchronous socket 297db96d56Sopenharmony_ciservice clients and servers. 307db96d56Sopenharmony_ci 317db96d56Sopenharmony_ci.. include:: ../includes/wasm-notavail.rst 327db96d56Sopenharmony_ci 337db96d56Sopenharmony_ciThere are only two ways to have a program on a single processor do "more than 347db96d56Sopenharmony_cione thing at a time." Multi-threaded programming is the simplest and most 357db96d56Sopenharmony_cipopular way to do it, but there is another very different technique, that lets 367db96d56Sopenharmony_ciyou have nearly all the advantages of multi-threading, without actually using 377db96d56Sopenharmony_cimultiple threads. It's really only practical if your program is largely I/O 387db96d56Sopenharmony_cibound. If your program is processor bound, then pre-emptive scheduled threads 397db96d56Sopenharmony_ciare probably what you really need. Network servers are rarely processor 407db96d56Sopenharmony_cibound, however. 417db96d56Sopenharmony_ci 427db96d56Sopenharmony_ciIf your operating system supports the :c:func:`select` system call in its I/O 437db96d56Sopenharmony_cilibrary (and nearly all do), then you can use it to juggle multiple 447db96d56Sopenharmony_cicommunication channels at once; doing other work while your I/O is taking 457db96d56Sopenharmony_ciplace in the "background." Although this strategy can seem strange and 467db96d56Sopenharmony_cicomplex, especially at first, it is in many ways easier to understand and 477db96d56Sopenharmony_cicontrol than multi-threaded programming. The :mod:`asyncore` module solves 487db96d56Sopenharmony_cimany of the difficult problems for you, making the task of building 497db96d56Sopenharmony_cisophisticated high-performance network servers and clients a snap. For 507db96d56Sopenharmony_ci"conversational" applications and protocols the companion :mod:`asynchat` 517db96d56Sopenharmony_cimodule is invaluable. 527db96d56Sopenharmony_ci 537db96d56Sopenharmony_ciThe basic idea behind both modules is to create one or more network 547db96d56Sopenharmony_ci*channels*, instances of class :class:`asyncore.dispatcher` and 557db96d56Sopenharmony_ci:class:`asynchat.async_chat`. Creating the channels adds them to a global 567db96d56Sopenharmony_cimap, used by the :func:`loop` function if you do not provide it with your own 577db96d56Sopenharmony_ci*map*. 587db96d56Sopenharmony_ci 597db96d56Sopenharmony_ciOnce the initial channel(s) is(are) created, calling the :func:`loop` function 607db96d56Sopenharmony_ciactivates channel service, which continues until the last channel (including 617db96d56Sopenharmony_ciany that have been added to the map during asynchronous service) is closed. 627db96d56Sopenharmony_ci 637db96d56Sopenharmony_ci 647db96d56Sopenharmony_ci.. function:: loop([timeout[, use_poll[, map[,count]]]]) 657db96d56Sopenharmony_ci 667db96d56Sopenharmony_ci Enter a polling loop that terminates after count passes or all open 677db96d56Sopenharmony_ci channels have been closed. All arguments are optional. The *count* 687db96d56Sopenharmony_ci parameter defaults to ``None``, resulting in the loop terminating only when all 697db96d56Sopenharmony_ci channels have been closed. The *timeout* argument sets the timeout 707db96d56Sopenharmony_ci parameter for the appropriate :func:`~select.select` or :func:`~select.poll` 717db96d56Sopenharmony_ci call, measured in seconds; the default is 30 seconds. The *use_poll* 727db96d56Sopenharmony_ci parameter, if true, indicates that :func:`~select.poll` should be used in 737db96d56Sopenharmony_ci preference to :func:`~select.select` (the default is ``False``). 747db96d56Sopenharmony_ci 757db96d56Sopenharmony_ci The *map* parameter is a dictionary whose items are the channels to watch. 767db96d56Sopenharmony_ci As channels are closed they are deleted from their map. If *map* is 777db96d56Sopenharmony_ci omitted, a global map is used. Channels (instances of 787db96d56Sopenharmony_ci :class:`asyncore.dispatcher`, :class:`asynchat.async_chat` and subclasses 797db96d56Sopenharmony_ci thereof) can freely be mixed in the map. 807db96d56Sopenharmony_ci 817db96d56Sopenharmony_ci 827db96d56Sopenharmony_ci.. class:: dispatcher() 837db96d56Sopenharmony_ci 847db96d56Sopenharmony_ci The :class:`dispatcher` class is a thin wrapper around a low-level socket 857db96d56Sopenharmony_ci object. To make it more useful, it has a few methods for event-handling 867db96d56Sopenharmony_ci which are called from the asynchronous loop. Otherwise, it can be treated 877db96d56Sopenharmony_ci as a normal non-blocking socket object. 887db96d56Sopenharmony_ci 897db96d56Sopenharmony_ci The firing of low-level events at certain times or in certain connection 907db96d56Sopenharmony_ci states tells the asynchronous loop that certain higher-level events have 917db96d56Sopenharmony_ci taken place. For example, if we have asked for a socket to connect to 927db96d56Sopenharmony_ci another host, we know that the connection has been made when the socket 937db96d56Sopenharmony_ci becomes writable for the first time (at this point you know that you may 947db96d56Sopenharmony_ci write to it with the expectation of success). The implied higher-level 957db96d56Sopenharmony_ci events are: 967db96d56Sopenharmony_ci 977db96d56Sopenharmony_ci +----------------------+----------------------------------------+ 987db96d56Sopenharmony_ci | Event | Description | 997db96d56Sopenharmony_ci +======================+========================================+ 1007db96d56Sopenharmony_ci | ``handle_connect()`` | Implied by the first read or write | 1017db96d56Sopenharmony_ci | | event | 1027db96d56Sopenharmony_ci +----------------------+----------------------------------------+ 1037db96d56Sopenharmony_ci | ``handle_close()`` | Implied by a read event with no data | 1047db96d56Sopenharmony_ci | | available | 1057db96d56Sopenharmony_ci +----------------------+----------------------------------------+ 1067db96d56Sopenharmony_ci | ``handle_accepted()``| Implied by a read event on a listening | 1077db96d56Sopenharmony_ci | | socket | 1087db96d56Sopenharmony_ci +----------------------+----------------------------------------+ 1097db96d56Sopenharmony_ci 1107db96d56Sopenharmony_ci During asynchronous processing, each mapped channel's :meth:`readable` and 1117db96d56Sopenharmony_ci :meth:`writable` methods are used to determine whether the channel's socket 1127db96d56Sopenharmony_ci should be added to the list of channels :c:func:`select`\ ed or 1137db96d56Sopenharmony_ci :c:func:`poll`\ ed for read and write events. 1147db96d56Sopenharmony_ci 1157db96d56Sopenharmony_ci Thus, the set of channel events is larger than the basic socket events. The 1167db96d56Sopenharmony_ci full set of methods that can be overridden in your subclass follows: 1177db96d56Sopenharmony_ci 1187db96d56Sopenharmony_ci 1197db96d56Sopenharmony_ci .. method:: handle_read() 1207db96d56Sopenharmony_ci 1217db96d56Sopenharmony_ci Called when the asynchronous loop detects that a :meth:`read` call on the 1227db96d56Sopenharmony_ci channel's socket will succeed. 1237db96d56Sopenharmony_ci 1247db96d56Sopenharmony_ci 1257db96d56Sopenharmony_ci .. method:: handle_write() 1267db96d56Sopenharmony_ci 1277db96d56Sopenharmony_ci Called when the asynchronous loop detects that a writable socket can be 1287db96d56Sopenharmony_ci written. Often this method will implement the necessary buffering for 1297db96d56Sopenharmony_ci performance. For example:: 1307db96d56Sopenharmony_ci 1317db96d56Sopenharmony_ci def handle_write(self): 1327db96d56Sopenharmony_ci sent = self.send(self.buffer) 1337db96d56Sopenharmony_ci self.buffer = self.buffer[sent:] 1347db96d56Sopenharmony_ci 1357db96d56Sopenharmony_ci 1367db96d56Sopenharmony_ci .. method:: handle_expt() 1377db96d56Sopenharmony_ci 1387db96d56Sopenharmony_ci Called when there is out of band (OOB) data for a socket connection. This 1397db96d56Sopenharmony_ci will almost never happen, as OOB is tenuously supported and rarely used. 1407db96d56Sopenharmony_ci 1417db96d56Sopenharmony_ci 1427db96d56Sopenharmony_ci .. method:: handle_connect() 1437db96d56Sopenharmony_ci 1447db96d56Sopenharmony_ci Called when the active opener's socket actually makes a connection. Might 1457db96d56Sopenharmony_ci send a "welcome" banner, or initiate a protocol negotiation with the 1467db96d56Sopenharmony_ci remote endpoint, for example. 1477db96d56Sopenharmony_ci 1487db96d56Sopenharmony_ci 1497db96d56Sopenharmony_ci .. method:: handle_close() 1507db96d56Sopenharmony_ci 1517db96d56Sopenharmony_ci Called when the socket is closed. 1527db96d56Sopenharmony_ci 1537db96d56Sopenharmony_ci 1547db96d56Sopenharmony_ci .. method:: handle_error() 1557db96d56Sopenharmony_ci 1567db96d56Sopenharmony_ci Called when an exception is raised and not otherwise handled. The default 1577db96d56Sopenharmony_ci version prints a condensed traceback. 1587db96d56Sopenharmony_ci 1597db96d56Sopenharmony_ci 1607db96d56Sopenharmony_ci .. method:: handle_accept() 1617db96d56Sopenharmony_ci 1627db96d56Sopenharmony_ci Called on listening channels (passive openers) when a connection can be 1637db96d56Sopenharmony_ci established with a new remote endpoint that has issued a :meth:`connect` 1647db96d56Sopenharmony_ci call for the local endpoint. Deprecated in version 3.2; use 1657db96d56Sopenharmony_ci :meth:`handle_accepted` instead. 1667db96d56Sopenharmony_ci 1677db96d56Sopenharmony_ci .. deprecated:: 3.2 1687db96d56Sopenharmony_ci 1697db96d56Sopenharmony_ci 1707db96d56Sopenharmony_ci .. method:: handle_accepted(sock, addr) 1717db96d56Sopenharmony_ci 1727db96d56Sopenharmony_ci Called on listening channels (passive openers) when a connection has been 1737db96d56Sopenharmony_ci established with a new remote endpoint that has issued a :meth:`connect` 1747db96d56Sopenharmony_ci call for the local endpoint. *sock* is a *new* socket object usable to 1757db96d56Sopenharmony_ci send and receive data on the connection, and *addr* is the address 1767db96d56Sopenharmony_ci bound to the socket on the other end of the connection. 1777db96d56Sopenharmony_ci 1787db96d56Sopenharmony_ci .. versionadded:: 3.2 1797db96d56Sopenharmony_ci 1807db96d56Sopenharmony_ci 1817db96d56Sopenharmony_ci .. method:: readable() 1827db96d56Sopenharmony_ci 1837db96d56Sopenharmony_ci Called each time around the asynchronous loop to determine whether a 1847db96d56Sopenharmony_ci channel's socket should be added to the list on which read events can 1857db96d56Sopenharmony_ci occur. The default method simply returns ``True``, indicating that by 1867db96d56Sopenharmony_ci default, all channels will be interested in read events. 1877db96d56Sopenharmony_ci 1887db96d56Sopenharmony_ci 1897db96d56Sopenharmony_ci .. method:: writable() 1907db96d56Sopenharmony_ci 1917db96d56Sopenharmony_ci Called each time around the asynchronous loop to determine whether a 1927db96d56Sopenharmony_ci channel's socket should be added to the list on which write events can 1937db96d56Sopenharmony_ci occur. The default method simply returns ``True``, indicating that by 1947db96d56Sopenharmony_ci default, all channels will be interested in write events. 1957db96d56Sopenharmony_ci 1967db96d56Sopenharmony_ci 1977db96d56Sopenharmony_ci In addition, each channel delegates or extends many of the socket methods. 1987db96d56Sopenharmony_ci Most of these are nearly identical to their socket partners. 1997db96d56Sopenharmony_ci 2007db96d56Sopenharmony_ci 2017db96d56Sopenharmony_ci .. method:: create_socket(family=socket.AF_INET, type=socket.SOCK_STREAM) 2027db96d56Sopenharmony_ci 2037db96d56Sopenharmony_ci This is identical to the creation of a normal socket, and will use the 2047db96d56Sopenharmony_ci same options for creation. Refer to the :mod:`socket` documentation for 2057db96d56Sopenharmony_ci information on creating sockets. 2067db96d56Sopenharmony_ci 2077db96d56Sopenharmony_ci .. versionchanged:: 3.3 2087db96d56Sopenharmony_ci *family* and *type* arguments can be omitted. 2097db96d56Sopenharmony_ci 2107db96d56Sopenharmony_ci 2117db96d56Sopenharmony_ci .. method:: connect(address) 2127db96d56Sopenharmony_ci 2137db96d56Sopenharmony_ci As with the normal socket object, *address* is a tuple with the first 2147db96d56Sopenharmony_ci element the host to connect to, and the second the port number. 2157db96d56Sopenharmony_ci 2167db96d56Sopenharmony_ci 2177db96d56Sopenharmony_ci .. method:: send(data) 2187db96d56Sopenharmony_ci 2197db96d56Sopenharmony_ci Send *data* to the remote end-point of the socket. 2207db96d56Sopenharmony_ci 2217db96d56Sopenharmony_ci 2227db96d56Sopenharmony_ci .. method:: recv(buffer_size) 2237db96d56Sopenharmony_ci 2247db96d56Sopenharmony_ci Read at most *buffer_size* bytes from the socket's remote end-point. An 2257db96d56Sopenharmony_ci empty bytes object implies that the channel has been closed from the 2267db96d56Sopenharmony_ci other end. 2277db96d56Sopenharmony_ci 2287db96d56Sopenharmony_ci Note that :meth:`recv` may raise :exc:`BlockingIOError` , even though 2297db96d56Sopenharmony_ci :func:`select.select` or :func:`select.poll` has reported the socket 2307db96d56Sopenharmony_ci ready for reading. 2317db96d56Sopenharmony_ci 2327db96d56Sopenharmony_ci 2337db96d56Sopenharmony_ci .. method:: listen(backlog) 2347db96d56Sopenharmony_ci 2357db96d56Sopenharmony_ci Listen for connections made to the socket. The *backlog* argument 2367db96d56Sopenharmony_ci specifies the maximum number of queued connections and should be at least 2377db96d56Sopenharmony_ci 1; the maximum value is system-dependent (usually 5). 2387db96d56Sopenharmony_ci 2397db96d56Sopenharmony_ci 2407db96d56Sopenharmony_ci .. method:: bind(address) 2417db96d56Sopenharmony_ci 2427db96d56Sopenharmony_ci Bind the socket to *address*. The socket must not already be bound. (The 2437db96d56Sopenharmony_ci format of *address* depends on the address family --- refer to the 2447db96d56Sopenharmony_ci :mod:`socket` documentation for more information.) To mark 2457db96d56Sopenharmony_ci the socket as re-usable (setting the :const:`SO_REUSEADDR` option), call 2467db96d56Sopenharmony_ci the :class:`dispatcher` object's :meth:`set_reuse_addr` method. 2477db96d56Sopenharmony_ci 2487db96d56Sopenharmony_ci 2497db96d56Sopenharmony_ci .. method:: accept() 2507db96d56Sopenharmony_ci 2517db96d56Sopenharmony_ci Accept a connection. The socket must be bound to an address and listening 2527db96d56Sopenharmony_ci for connections. The return value can be either ``None`` or a pair 2537db96d56Sopenharmony_ci ``(conn, address)`` where *conn* is a *new* socket object usable to send 2547db96d56Sopenharmony_ci and receive data on the connection, and *address* is the address bound to 2557db96d56Sopenharmony_ci the socket on the other end of the connection. 2567db96d56Sopenharmony_ci When ``None`` is returned it means the connection didn't take place, in 2577db96d56Sopenharmony_ci which case the server should just ignore this event and keep listening 2587db96d56Sopenharmony_ci for further incoming connections. 2597db96d56Sopenharmony_ci 2607db96d56Sopenharmony_ci 2617db96d56Sopenharmony_ci .. method:: close() 2627db96d56Sopenharmony_ci 2637db96d56Sopenharmony_ci Close the socket. All future operations on the socket object will fail. 2647db96d56Sopenharmony_ci The remote end-point will receive no more data (after queued data is 2657db96d56Sopenharmony_ci flushed). Sockets are automatically closed when they are 2667db96d56Sopenharmony_ci garbage-collected. 2677db96d56Sopenharmony_ci 2687db96d56Sopenharmony_ci 2697db96d56Sopenharmony_ci.. class:: dispatcher_with_send() 2707db96d56Sopenharmony_ci 2717db96d56Sopenharmony_ci A :class:`dispatcher` subclass which adds simple buffered output capability, 2727db96d56Sopenharmony_ci useful for simple clients. For more sophisticated usage use 2737db96d56Sopenharmony_ci :class:`asynchat.async_chat`. 2747db96d56Sopenharmony_ci 2757db96d56Sopenharmony_ci.. class:: file_dispatcher() 2767db96d56Sopenharmony_ci 2777db96d56Sopenharmony_ci A file_dispatcher takes a file descriptor or :term:`file object` along 2787db96d56Sopenharmony_ci with an optional map argument and wraps it for use with the :c:func:`poll` 2797db96d56Sopenharmony_ci or :c:func:`loop` functions. If provided a file object or anything with a 2807db96d56Sopenharmony_ci :c:func:`fileno` method, that method will be called and passed to the 2817db96d56Sopenharmony_ci :class:`file_wrapper` constructor. 2827db96d56Sopenharmony_ci 2837db96d56Sopenharmony_ci .. availability:: Unix. 2847db96d56Sopenharmony_ci 2857db96d56Sopenharmony_ci.. class:: file_wrapper() 2867db96d56Sopenharmony_ci 2877db96d56Sopenharmony_ci A file_wrapper takes an integer file descriptor and calls :func:`os.dup` to 2887db96d56Sopenharmony_ci duplicate the handle so that the original handle may be closed independently 2897db96d56Sopenharmony_ci of the file_wrapper. This class implements sufficient methods to emulate a 2907db96d56Sopenharmony_ci socket for use by the :class:`file_dispatcher` class. 2917db96d56Sopenharmony_ci 2927db96d56Sopenharmony_ci .. availability:: Unix. 2937db96d56Sopenharmony_ci 2947db96d56Sopenharmony_ci 2957db96d56Sopenharmony_ci.. _asyncore-example-1: 2967db96d56Sopenharmony_ci 2977db96d56Sopenharmony_ciasyncore Example basic HTTP client 2987db96d56Sopenharmony_ci---------------------------------- 2997db96d56Sopenharmony_ci 3007db96d56Sopenharmony_ciHere is a very basic HTTP client that uses the :class:`dispatcher` class to 3017db96d56Sopenharmony_ciimplement its socket handling:: 3027db96d56Sopenharmony_ci 3037db96d56Sopenharmony_ci import asyncore 3047db96d56Sopenharmony_ci 3057db96d56Sopenharmony_ci class HTTPClient(asyncore.dispatcher): 3067db96d56Sopenharmony_ci 3077db96d56Sopenharmony_ci def __init__(self, host, path): 3087db96d56Sopenharmony_ci asyncore.dispatcher.__init__(self) 3097db96d56Sopenharmony_ci self.create_socket() 3107db96d56Sopenharmony_ci self.connect( (host, 80) ) 3117db96d56Sopenharmony_ci self.buffer = bytes('GET %s HTTP/1.0\r\nHost: %s\r\n\r\n' % 3127db96d56Sopenharmony_ci (path, host), 'ascii') 3137db96d56Sopenharmony_ci 3147db96d56Sopenharmony_ci def handle_connect(self): 3157db96d56Sopenharmony_ci pass 3167db96d56Sopenharmony_ci 3177db96d56Sopenharmony_ci def handle_close(self): 3187db96d56Sopenharmony_ci self.close() 3197db96d56Sopenharmony_ci 3207db96d56Sopenharmony_ci def handle_read(self): 3217db96d56Sopenharmony_ci print(self.recv(8192)) 3227db96d56Sopenharmony_ci 3237db96d56Sopenharmony_ci def writable(self): 3247db96d56Sopenharmony_ci return (len(self.buffer) > 0) 3257db96d56Sopenharmony_ci 3267db96d56Sopenharmony_ci def handle_write(self): 3277db96d56Sopenharmony_ci sent = self.send(self.buffer) 3287db96d56Sopenharmony_ci self.buffer = self.buffer[sent:] 3297db96d56Sopenharmony_ci 3307db96d56Sopenharmony_ci 3317db96d56Sopenharmony_ci client = HTTPClient('www.python.org', '/') 3327db96d56Sopenharmony_ci asyncore.loop() 3337db96d56Sopenharmony_ci 3347db96d56Sopenharmony_ci.. _asyncore-example-2: 3357db96d56Sopenharmony_ci 3367db96d56Sopenharmony_ciasyncore Example basic echo server 3377db96d56Sopenharmony_ci---------------------------------- 3387db96d56Sopenharmony_ci 3397db96d56Sopenharmony_ciHere is a basic echo server that uses the :class:`dispatcher` class to accept 3407db96d56Sopenharmony_ciconnections and dispatches the incoming connections to a handler:: 3417db96d56Sopenharmony_ci 3427db96d56Sopenharmony_ci import asyncore 3437db96d56Sopenharmony_ci 3447db96d56Sopenharmony_ci class EchoHandler(asyncore.dispatcher_with_send): 3457db96d56Sopenharmony_ci 3467db96d56Sopenharmony_ci def handle_read(self): 3477db96d56Sopenharmony_ci data = self.recv(8192) 3487db96d56Sopenharmony_ci if data: 3497db96d56Sopenharmony_ci self.send(data) 3507db96d56Sopenharmony_ci 3517db96d56Sopenharmony_ci class EchoServer(asyncore.dispatcher): 3527db96d56Sopenharmony_ci 3537db96d56Sopenharmony_ci def __init__(self, host, port): 3547db96d56Sopenharmony_ci asyncore.dispatcher.__init__(self) 3557db96d56Sopenharmony_ci self.create_socket() 3567db96d56Sopenharmony_ci self.set_reuse_addr() 3577db96d56Sopenharmony_ci self.bind((host, port)) 3587db96d56Sopenharmony_ci self.listen(5) 3597db96d56Sopenharmony_ci 3607db96d56Sopenharmony_ci def handle_accepted(self, sock, addr): 3617db96d56Sopenharmony_ci print('Incoming connection from %s' % repr(addr)) 3627db96d56Sopenharmony_ci handler = EchoHandler(sock) 3637db96d56Sopenharmony_ci 3647db96d56Sopenharmony_ci server = EchoServer('localhost', 8080) 3657db96d56Sopenharmony_ci asyncore.loop() 366