Reputation: 4656
I'm curious to see how I can create a UDP proxy server using the async module. I tried earlier today with Twisted, but wasn't making much headway. I did find some simple solutions here on stackoverflow using sockets directly, but i'm wondering if this is possible using the async lib.
For clarity, what I'm looking for is:
Step 1: client A (can be many) speaks to proxy B Step 2: proxy B sends the request along to server C. Step 3: Server C responds to proxy B Sep 4: Proxy B responds to client A.
Here's what I have so far:
import asyncio
class EchoServerProtocol(asyncio.DatagramProtocol):
def connection_made(self, transport):
self.transport = transport
def datagram_received(self, data, addr, args=None):
message = data
server_addr = ('localhost', 27015)
print('Received %r from %s' % (message, addr))
print('Send %r to %s' % (message, server_addr))
self.transport.sendto(data, server_addr)
loop = asyncio.get_event_loop()
print("Starting UDP server")
# One protocol instance will be created to serve all client requests
listen = loop.create_datagram_endpoint(
EchoServerProtocol,
local_addr=('0.0.0.0', 27016),
)
transport, protocol = loop.run_until_complete(listen)
try:
loop.run_forever()
except KeyboardInterrupt:
pass
transport.close()
loop.close()
The above is basically this:
https://docs.python.org/3/library/asyncio-protocol.html#udp-echo-server-protocol
What I have will get you to step 3, but of course fails at step 4. It sends it back to server C.
You will note that one of the other protocol examples, EchoServerClientProtocol
, creates a new instance for each connection. I assume I need to create a new instance for every connection, I believe, because then I can store the original address in the instance, and return that. I assume this doesn't apply to create_datagram_endpoint
, or I can't figure out how to do it.
There might be a better approach though.
Upvotes: 3
Views: 3675
Reputation: 13425
You need a local endpoint for server B, plus a remote endpoint to server C for each client A.
Here is a possible implementation.
Also, you might be interested in this module providing high-level UDP endpoints for asyncio.
Upvotes: 4