Last active
November 23, 2015 15:21
-
-
Save SpotlightKid/26e2e8f8889c897a7eb8 to your computer and use it in GitHub Desktop.
A simple single-connection, blocking UDP echo server, which listens on IPv4 and IP6 simultaneously
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
# | |
# udpserver.py | |
# | |
"""A minimal test UDP (echo) server supporting IPv4 and IPv6.""" | |
import argparse | |
import logging | |
import socket | |
import sys | |
log = logging.getLogger(__name__) | |
MAX_DGRAM_SIZE = 1472 | |
DEFAULT_ADDRESS = '::' | |
DEFAULT_PORT = 9000 | |
def main(args=None): | |
ap = argparse.ArgumentParser() | |
ap.add_argument('-v', '--verbose', action="store_true", | |
help="Enable debug logging") | |
ap.add_argument('-e', '--echo', action="store_true", | |
help="Echo received data back to sender") | |
ap.add_argument('-a', '--address', default=DEFAULT_ADDRESS, | |
help="UDP server IP address (default: %(default)s)") | |
ap.add_argument('-p', '--port', type=int, default=DEFAULT_PORT, | |
help="UDP server port (default: %(default)s)") | |
args = ap.parse_args(args if args is not None else sys.argv[1:]) | |
logging.basicConfig(level=logging.DEBUG if args.verbose else logging.INFO) | |
af = socket.AF_INET6 if '::' in args.address else socket.AF_INET | |
sock = socket.socket(af, socket.SOCK_DGRAM) | |
if af == socket.AF_INET6: | |
sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0) | |
log.debug("Created UDP socket.") | |
addr = socket.getaddrinfo(args.address, args.port, af, socket.SOCK_DGRAM) | |
sock.bind(addr[0][4]) | |
log.debug("Bound socket to port %i on '%s'.", args.port, args.address) | |
# In each loop iteration, block until one UDP datagram with | |
# a maximum size of up to MAX_DGRAM_SIZE is received and | |
# print out the received data and the address info of the sender. | |
# Optionally, echo back the data to the sender. | |
try: | |
log.debug("Entering receive loop...") | |
while True: | |
data, addr = sock.recvfrom(MAX_DGRAM_SIZE) | |
log.info("Received data: %r", data) | |
log.info("Sender: %r", addr) | |
if args.echo: | |
sock.sendto(data, addr) | |
except KeyboardInterrupt: | |
pass | |
finally: | |
sock.close() | |
log.info("Bye!") | |
if __name__ == '__main__': | |
sys.exit(main(sys.argv[1:]) or 0) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment