Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(37)

Unified Diff: Lib/socket.py

Issue 17561: Add socket.create_server_sock() convenience function
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | Lib/test/test_socket.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
--- a/Lib/socket.py
+++ b/Lib/socket.py
@@ -435,3 +435,75 @@
raise err
else:
raise error("getaddrinfo returns an empty list")
+
+def has_dual_stack():
+ """Return True if kernel allows creating a socket which is able to
+ listen for both IPv4 and IPv6 connections.
Charles-François Natali 2013/04/04 08:44:29 The term "dual stack" is a bit confusing: it just
+ """
+ if not has_ipv6 \
+ or not hasattr(_socket, 'AF_INET6') \
+ or not hasattr(_socket, 'IPV6_V6ONLY'):
Charles-François Natali 2013/04/04 08:44:29 I think PEP8 discourages line breaks using '\': pa
+ return False
+ try:
+ with socket(AF_INET6, SOCK_STREAM) as sock:
+ if not sock.getsockopt(IPPROTO_IPV6, IPV6_V6ONLY):
+ return True
+ else:
+ sock.setsockopt(IPPROTO_IPV6, IPV6_V6ONLY, False)
+ return True
+ except error:
+ return False
+
+def create_server_sock(address,
+ reuse_addr=os.name == 'posix' and sys.platform != 'cygwin',
+ queue_size=5,
+ dual_stack=has_dual_stack()):
Charles-François Natali 2013/04/04 08:44:29 Same thing here, I think it complicates the signat
+ """Convenience function which creates a TCP server bound to
+ *address* and return the socket object.
+
Charles-François Natali 2013/04/04 08:44:29 The *reuse_addr* argument is not documented in the
+ Internally it takes care of choosing the right address family
+ (IPv4 or IPv6) depending on the host specified in *address*.
+ If *host* is an empty string or None all interfaces are assumed.
+ If dual stack is supported by kernel the socket will be able to
+ listen for both IPv4 and IPv6 connections.
+
+ The returned socket can be used to accept() new connections as in:
+
+ >>> server = create_server_sock((None, 8000))
+ >>> while True:
+ ... sock, addr = server.accept()
+ ... # handle new sock connection
+ """
+ AF_INET6_ = getattr(_socket, "AF_INET6", 0)
Charles-François Natali 2013/04/04 08:44:29 It might be possible to use socket.has_ipv6.
+ host, port = address
+ if host == "":
+ # http://mail.python.org/pipermail/python-ideas/2013-March/019937.html
+ host = None
+ # if dual stack is supported and no host was specified assume '::'
+ # (IPv6 / all interfaces)
+ if host is None and dual_stack:
+ host = "::"
+ err = None
+ info = getaddrinfo(host, port, AF_UNSPEC, SOCK_STREAM, 0, AI_PASSIVE)
+ for res in info:
+ af, socktype, proto, canonname, sa = res
+ sock = None
+ try:
+ sock = socket(af, socktype, proto)
+ if reuse_addr:
+ sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
+ if af == AF_INET6_ and dual_stack:
+ if sock.getsockopt(IPPROTO_IPV6, IPV6_V6ONLY):
+ sock.setsockopt(IPPROTO_IPV6, IPV6_V6ONLY, False)
+ sock.bind(sa)
+ sock.listen(queue_size)
+ return sock
+ except error as _:
+ err = _
+ if sock is not None:
+ sock.close()
+
+ if err is not None:
+ raise err
+ else:
+ raise error("getaddrinfo returns an empty list")
« no previous file with comments | « no previous file | Lib/test/test_socket.py » ('j') | no next file with comments »

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+