Skip to main content

Asyncio UDP server with traffic throttling

Project description

Asyncio UDP server

Build Status

Yet another async UDP server. Based on bare sockets.

Killer-feature: bandwidth throttling for uploading & downloading.

UDPServer.__init__

UDP server constructor.

Arguments:

  • upload_speed — maximum outgoing traffic speed in "byter per second" (default: 0 — unlimited);
  • download_speed — maximum incoming traffic speed in "byter per second" (default: 0 — unlimited);
  • recv_max_size — maximum socket window size for receiving (default: 262144).

UDPServer.run

Server startup function.

Arguments:

  • host — socket bind host/interface (e.g. "0.0.0.0", "127.0.0.1" or "localhost");
  • port — socket listen port;
  • loop — event loop (optional).

UDPServer.send

Enqueue data for sending.

Arguments:

  • databytes or bytearray data for sending;
  • addr — tuple of host and port (e.g. ("127.0.0.1", 9876) or ("some.domain.com", 5556)).

Events

  • UDPServer.connection_made() — virtual method, call after socket bind successfully.
  • UDPServer.datagram_received(data, addr) — async virtual method, call each time when server got incoming data.

Example

import datetime


class MyUDPServer(UDPServer):
    def connection_made(self):
        # Start intense sending
        asyncio.ensure_future(self.do_send(), loop=self.loop)

    async def datagram_received(self, data, addr):
        # Override virtual method and process incoming data
        print(datetime.datetime.now(), addr, data)

    async def do_send(self):
        while True:
            # Any payload
            payload = b'd1:ad2:id20:k\xe7\x90\xcd\x0c_R\xfe\x82\xeb\xa8 x\x14\xb4-\x8e0\xe5\x086:target20:\x11\x8e\xcc,\x89\xa4\x99\xf98E\x98\x7f!\xa7w\rz\x1b\x14de1:q9:find_node1:t2:#K1:y1:qe'
            # Delay for prevent tasks concurency
            await asyncio.sleep(0.001)
            # Enqueue data for send
            self.send(payload, ("router.bittorrent.com", 6881))


if __name__ == '__main__':
    # Bandwidth speed is 100 bytes per second
    server = MyUDPServer(download_speed=100, upload_speed=100)
    server.run("0.0.0.0", 12346)

Output:

2019-06-04 16:04:07.761576 ('67.215.246.10', 6881) b'd2:ip6:Z\x97\'X0:1:rd2:id20:2\xf5NisQ\xffJ\xec)\xcd\xba\xab\xf2\xfb\xe3F|\xc2g5:nodes416:\x02\xf7\xb7\x1d\x94\xb1\x00\xe8\x84\xca\x9c\xc3\xb09\xbb\x04*P\x8cQ\x1f\x7fF\xa9\x1a\xe1\x00\x13\x99W\x14\xb1\x99\x8b\xff\x8e\xda2\xb3 \xac\x82\xef0sCl\xda+G\xc4\x91\x17bO,\xe8\xbc\x9e\xeb+\xfc.\xe6\xf8\xb0\x82\xee~\x17 \xebvF\x83\xf8\x83\xc1\xdaK\x1b\x83\x17\xfb!\xab\x1e\x97T\xa3\xfa\x9a\x14Q$\x06)\\\xad>O\x03\xc4\x91\x9f/7\xf6>]|\xe0\xc6f\x1eq\xfd\xcc\x0e\xbe\xd0\x85\xde\xf9\xbeJc\xe3e\xe5\x9e\x9d\xca})P\xa5\xfd\x8c\xb66\xb9\xba\x0f\xfc\xb1\xb9\xa3 E\xc9*\x1f\xd1I\xb1r9\xfaI\xf1\xf1\xbb\xe9\xeb\xb3\xa6\xdb<\x87\x0c>\x99$^R\xbc\x85\xd3\xb3C\xab}\xbf6\xcc\x11\x7fv\xde\r\xed\xa4q\xdd\x04#\x8d\xd8j7$[\xe5e\\\xf9V\x166\xb1P\x7f\xa01v\xf49\xb9\x9a\x12*\xad<Q@\xa6\x8d\xd5\xe6wN\xa2\x87\xaf|\xb4KslP\xf5\xd0h\xaf\x1c\xb5\xb6\xc0\xc9\xfa\x0c\xfe\xe8\xb92\n\xb7\xda"8\x019\x95\xe8\xef\xc1u\xa4$\xe5\x0c!\xe2\x10j\xff\x10\xeb\xffu\x02\x87t\x9f\x01|\xa4b\x87\xc4\xa0.\xd2g\x9f\xf6\xd1\xc2\xfd\xef\xa1!a\x04\xdf<\x97)\xbe\xd1\x81l\xb1?W\t\xbb\xc1\xbd\x04\x8ec\xf8\x08\xcd\x1av\x1a\xa9\xb3R^\xb5{\x11\x1a\xe1C\xe1\xb43\x04\x03Wl\xd1E\xa6\x0f\xf7\xcbQ\t\x84W\xd6\xebD\'\xdd=\xb1\xc9\xed\xc6C\xf9\x7f\xfbg\xf9$\x0e\x0b~\xa5\xae\xfdnvr\xe7\xc4.\xf8(\x90\xa4\x84C\xe9\xccK4r\xc6=\xf1\xc09\xdf{\xfc\x10\xe9\xd9\xd8\xa5\xdd.\x00\x88\x0e\xe7]e1:t2:#K1:y1:re'
2019-06-04 16:04:12.622861 ('67.215.246.10', 6881) b'd2:ip6:Z\x97\'X0:1:rd2:id20:2\xf5NisQ\xffJ\xec)\xcd\xba\xab\xf2\xfb\xe3F|\xc2g5:nodes416:\x1e\xe4\xb8\x96\xf5E;\x13\r\x89\n\x1c\xdb\xae2 \x9aP\xee\xcb\xa0\xb0\xcbq\xa4X\x80\x8c>\x91:M\xb67%kY\xc7\xb5\xe1\xe7\x901_u\\\xbd(g\xeb[\xa7-\x1fl\x1e\xd6\x93\xe8g\xdam\n;\xa8y \xf4K\x18\xe0\x11z\xfe\xa6\xf6\xc9\xcfe\xcb\xf9\x7f+"92\xfb/\xd8C>K\x1a\xf9\xe8#\x86\x8dy\x07\xa1\x94>\x81\x17_\xcd\xe9\x03?\x96pX\x1c\xe8v{\xa5W,_ \x0f|Oi\x8bg\xc5J\xfd#\x9e\xf7\xdd\xc4\xa4\xb9\xd0\x8f\xbd\x9d\x98\xfaD\x91N}U{j\xd7\xfak\')\xcdr(\xc3\xdc\xc6\xd7\x9b=\x1d\x12/\xa4\xd5A\x8f[\x98\x07\x10EHq#\xcc\xb8\xae\xf00\xd4\xfd(\xe5fj\xbb\xdd\xa5s\x8b\xec:\xb1\x1d\x93%)S\xdf.\xb3\x17\x95\x9b\xc8\xc0\x95"\x86\x81\x16\x8d]\xdau\x15S\xbcN:\x9d\x83I+Vk\xc4\x91\x0b9t\xbdv`\xb2\x8d7\xae\t\xb1\x8c\x96\x9f\x1c\xa0B\xd0\x93\xbfd\x8e\xe7\xdf`\x14\x13\'<\x92Pn:u\xa0\n\xc3\xcd\x01\x12H\xc65\xeb\xa2X\xc8\xd6\x0b\x81\x1b\xcf\x89\xbco$\x8a\xf97\x920u\xb8i\xde\x15\x19\xc4\x8f\xfb\xc0\xb1\xcf\x99\xd9e1\xf6u\x01\xb7\x1e\xc4\x80\xca\x0e\xcawuv\xc9\xaf[\x0b\xd4\x99\xf4[\xf1\x8ck\x1a\xe1r\xc3\xb4(\xb8ba\x98\x8b\x1e\xb4TN"\xa7F5B\xcb\x0f\x05\x9e\xed-b\x82\xb8\x8d\xed\xf7\xaf?,\xc5)z\xd2f\xc1\xda`.\xf0.!\xf2H\xbezs\xf3\x8c\t\x9c\x9d\xe8\x87Q\xf4\xe9\x8fJ\x0c\x16\xa8\xc55Q\x878<\x04.0Bc!\xade1:t2:#K1:y1:re'
2019-06-04 16:04:17.483860 ('67.215.246.10', 6881) b'd2:ip6:Z\x97\'X0:1:rd2:id20:2\xf5NisQ\xffJ\xec)\xcd\xba\xab\xf2\xfb\xe3F|\xc2g5:nodes416:k*[\x0c1\x9a\xb1\xd6\xe5>G\x0c\xac\xe3v0\xd0\xc2\xb7\x8cI\x93\xb7\xcd\xa8\xf1\xca(\xf8\xc0\xe0\xa6\xd4\xda*\xd4\xf1\xedc\xb4\xdf\xdf\xe2Q\x1a\xe9^\t\x8f\xfa\x1a\xe1$Wr\xe18\x1e\x9a\xce\xabW}\xbfLY\x05\xbd\xce\xa0\x0e\xb1_\x19\xdf>\xcaJS\x00H\xdf\x8d\xeedn\xd7\x07-\x9f\x8at\xb0\x14\xbe\x8d\x1d\x0eO\xa7\x97\xa3\x83\xa9\xb2\xff\xc9K\x97\x01m\xbc\xcb\xc3\x001vR\'s\xffyr\x82UF\\z\xafG\x8f\xc8U\xcf}+\x97\x90\xa2\x1b\x11\xef\xbfs\x80Q\xff\x1dc\x14%\xe8\x87\xac!\xadz\xbd\xcc\xbfq\xaex0\x7f(}jY[W\xdcsx\n|F\x86\xed\xa3\x1a\xe1,\x03\x87to\xd2X\x12\x00\x90\t\xcfu\xec_m\x15\x02\xe1\xf6\xd4\x98\x93\xfa\x1a\xe1\xc8\xa1-tC!\xd1X\xb0\xc9M\xc8\xf2\x94|\xca\x80j\xb8\x04\x05\xceB"_\xc3H\xf1i\x86\xb6\x07Z=\xc2\xb1`m\xab\xbc\xbeB\xb8\nVM]Q\x1cp\xc2L\x83\xca\xe7\xed\x1e\x10\x9d\xc9\xde\xdc[c\xef\xc2_]+N\xaaJ\xc9E0\xf5\x1b\x16q\xe1/\x97w>a\x94\x10\x0f\x94\xc2"\xd6\x89+\xa7\x01\\w%\x90Z_\x1a\xe1\xd9\xf5\xff\xb5D\xf2\x8d\xbc^[j\x16\xb9H\xe3.+\r\x87\xa5aU\xafMT\xec\x80\x02\x9bP\xf5\xc7\xe9\x8e\x9e\x94\x96\xc8\xcdu\xa1\xc1.\xa7 \xb5I\x0b\x9d\xef\xd0\x8ff\x91+\xc2\xe0\xeb/\xbe\x05\x87\xac\xd8\xb8vA\xe8?V\xa3\xfdJ\xc1\x9f\xe8\xc4\x91=\xc4\x16H\xbdP\x1fv5x9\x02\'N]Zh\xed\xc9\xc3\xb5\xae:\x04\xc8\x04e1:t2:#K1:y1:re'
2019-06-04 16:04:22.345648 ('67.215.246.10', 6881) b'd2:ip6:Z\x97\'X0:1:rd2:id20:2\xf5NisQ\xffJ\xec)\xcd\xba\xab\xf2\xfb\xe3F|\xc2g5:nodes416:+S\xdc\x8c\xc8%~ \x12\xd3\xd9@\xa9X4\x9at\xcc\x8a\xf9z\x08\x1d\x16h/\xf2}\xb7I\xd9\x8fP\x81(\x9d\xed\xae\xa5\xe5\xe4S1,\xf0-\xaeavL\xc4\x91~\xd5\x01`o\xa8\xc4\xe0\xfa \xa5\xf0\xf1~`\x0c\x19[+\x85\xbb\xd0\x0bp\xf3\x8c\xe98S\xcd`=n|\xa8\x8c\xa4~\xfc\xedg\xce\xff\x8f\x13}g\xfc\xc9)\xa8\x89L&]\\\xb3M\xc6NUE\x7f\xb8CQ\x82\xe1{C\xba\xaf\x884g\x9a\xf3\x8c\x1a\xe0\xbb\x1a\x12\xafCQ\x1e\x18\x91;\x80P\xee\xf0\xdc\t\xc1m.\xe4\x04\xda1\xff\x93?\xa0r\xc5\x1d\x9c\x1f\xc7\xf2\x0e[\xc9\tV4\x94\x02w\xc2\\b\x03+\x1a\xe1\xc4\x80#z0\x14\x9d}Kj\xbe\xf2>\xa5\xf8k\x12\x9a|u\xb0:\xc1,U\r\xc7kE\xa1UY\x1e~:r\x14\xb6p&\xd7\xdf\xaf>\x9b\xa5b\xb5\xcd\x1f\xc4\x91Z\xdf\x1a\x1f\xdb\x9a\x84\tu\xff\xda(\xddqy}nT\xaa\x8f%\x06.\xc9\xda\xe4\xc0\x9a\x03\x9c\x12?\xf1s[\xb1\xd7;\xe3)\xb9[o\r\xb6=\xb57\x98&\xc4\x91.\xd1\x87)5\xf5s\xb8\xc9z\xc4\x9d\x063Kw\xaf\xcc\x046\xdbN\xcf,\xf3\x8c\xaa\x85\xee\xd0e\xfa\xca\xd2\x93\x82\xe2\x98\xeaA\xdc\xbd\xaf\x97F\xe9r\x19\xb4i\xde~>\x82\xfb\xe9y#vJ\xe4\x8e\x0e\xd1\xee]\xe0qk(\xb2\x92\x95\xff\x02\n\x98\x9c"\xcaY\x8d\xb6\x81a\xa1\xf9\xc1\nX\xb4\x9e\xcfo\xbf\xa3j\x8fH1\'7\xc4\x91v\xd1_\xec\xe4\xe1\x1f\xcb\xd5\xbd\xf43\x0c\'"\x04\xa5\xa2\x0f\xd0\x05>+\xb1 Xe1:t2:#K1:y1:re'

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

aio-udp-server-0.0.1.tar.gz (6.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

aio_udp_server-0.0.1-py3-none-any.whl (18.4 kB view details)

Uploaded Python 3

File details

Details for the file aio-udp-server-0.0.1.tar.gz.

File metadata

  • Download URL: aio-udp-server-0.0.1.tar.gz
  • Upload date:
  • Size: 6.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.32.1 CPython/3.7.1

File hashes

Hashes for aio-udp-server-0.0.1.tar.gz
Algorithm Hash digest
SHA256 eda4060b4e2110e7fe9fcd3eb59253f9e1872a6f32ae2c3465efb7078bb7565d
MD5 1f5e712ce7429d0c6b52ff27ae30d8b2
BLAKE2b-256 0da89223fc2d71453b162fc18b54d8944685d505bb6357cc39156e9167d36936

See more details on using hashes here.

File details

Details for the file aio_udp_server-0.0.1-py3-none-any.whl.

File metadata

  • Download URL: aio_udp_server-0.0.1-py3-none-any.whl
  • Upload date:
  • Size: 18.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.32.1 CPython/3.7.1

File hashes

Hashes for aio_udp_server-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 12ae2b77554c4c0e359b3f04eebf3b4fafffcda9000b0a81d9d24c5ba19275c5
MD5 2892d7fb664533e1391d3581ee2d4ca3
BLAKE2b-256 18b7b7dde97f3d91dd5b43c88ccb8d5e31637251d3bec64b83244c0a1463bd6f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page