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

Delta Between Two Patch Sets: Lib/socket.py

Issue 17561: Add socket.create_server_sock() convenience function
Left Patch Set: Created 6 years, 10 months ago
Right Patch Set: Created 6 years, 10 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | Lib/test/test_socket.py » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 # Wrapper module for _socket, providing some additional facilities 1 # Wrapper module for _socket, providing some additional facilities
2 # implemented in Python. 2 # implemented in Python.
3 3
4 """\ 4 """\
5 This module provides socket operations and some related functions. 5 This module provides socket operations and some related functions.
6 On Unix, it supports IP (Internet Protocol) and Unix domain sockets. 6 On Unix, it supports IP (Internet Protocol) and Unix domain sockets.
7 On other systems, it only supports IP. Functions specific for a 7 On other systems, it only supports IP. Functions specific for a
8 socket are available as methods of the socket object. 8 socket are available as methods of the socket object.
9 9
10 Functions: 10 Functions:
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 except error as _: 429 except error as _:
430 err = _ 430 err = _
431 if sock is not None: 431 if sock is not None:
432 sock.close() 432 sock.close()
433 433
434 if err is not None: 434 if err is not None:
435 raise err 435 raise err
436 else: 436 else:
437 raise error("getaddrinfo returns an empty list") 437 raise error("getaddrinfo returns an empty list")
438 438
439 def has_dual_stack():
440 """Return True if kernel allows creating a socket which is able to
441 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
442 """
443 if not has_ipv6 \
444 or not hasattr(_socket, 'AF_INET6') \
445 or not hasattr(_socket, 'IPV6_V6ONLY'):
Charles-François Natali 2013/04/04 08:44:29 I think PEP8 discourages line breaks using '\': pa
446 return False
447 try:
448 with socket(AF_INET6, SOCK_STREAM) as sock:
449 if not sock.getsockopt(IPPROTO_IPV6, IPV6_V6ONLY):
450 return True
451 else:
452 sock.setsockopt(IPPROTO_IPV6, IPV6_V6ONLY, False)
453 return True
454 except error:
455 return False
456
439 def create_server_sock(address, 457 def create_server_sock(address,
440 reuse_addr=os.name == 'posix' and sys.platform != 'cygwin ', 458 reuse_addr=os.name == 'posix' and sys.platform != 'cygwin ',
441 queue_size=5): 459 queue_size=5,
460 dual_stack=has_dual_stack()):
Charles-François Natali 2013/04/04 08:44:29 Same thing here, I think it complicates the signat
442 """Convenience function which creates a TCP server bound to 461 """Convenience function which creates a TCP server bound to
443 *address* and return the socket object. 462 *address* and return the socket object.
463
Charles-François Natali 2013/04/04 08:44:29 The *reuse_addr* argument is not documented in the
444 Internally it takes care of choosing the right address family 464 Internally it takes care of choosing the right address family
445 (IPv4 or IPv6) depending on the host specified in *address*. 465 (IPv4 or IPv6) depending on the host specified in *address*.
446 The returned socket can then be used to accept() new connections 466 If *host* is an empty string or None all interfaces are assumed.
447 as in: 467 If dual stack is supported by kernel the socket will be able to
448 468 listen for both IPv4 and IPv6 connections.
449 >>> server = create_server_sock(('localhost', 8000)) 469
470 The returned socket can be used to accept() new connections as in:
471
472 >>> server = create_server_sock((None, 8000))
450 >>> while True: 473 >>> while True:
451 ... sock, addr = server.accept() 474 ... sock, addr = server.accept()
452 ... # handle new sock connection 475 ... # handle new sock connection
453 """ 476 """
477 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.
454 host, port = address 478 host, port = address
455 if host == "": 479 if host == "":
456 # http://mail.python.org/pipermail/python-ideas/2013-March/019937.html 480 # http://mail.python.org/pipermail/python-ideas/2013-March/019937.html
457 host = None 481 host = None
482 # if dual stack is supported and no host was specified assume '::'
483 # (IPv6 / all interfaces)
484 if host is None and dual_stack:
485 host = "::"
458 err = None 486 err = None
459 info = getaddrinfo(host, port, AF_UNSPEC, SOCK_STREAM, 0, AI_PASSIVE) 487 info = getaddrinfo(host, port, AF_UNSPEC, SOCK_STREAM, 0, AI_PASSIVE)
460 for res in getaddrinfo(host, port, 0, SOCK_STREAM): 488 for res in info:
461 af, socktype, proto, canonname, sa = res 489 af, socktype, proto, canonname, sa = res
462 sock = None 490 sock = None
463 try: 491 try:
464 sock = socket(af, socktype, proto) 492 sock = socket(af, socktype, proto)
465 if reuse_addr: 493 if reuse_addr:
466 sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) 494 sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
495 if af == AF_INET6_ and dual_stack:
496 if sock.getsockopt(IPPROTO_IPV6, IPV6_V6ONLY):
497 sock.setsockopt(IPPROTO_IPV6, IPV6_V6ONLY, False)
467 sock.bind(sa) 498 sock.bind(sa)
468 sock.listen(queue_size) 499 sock.listen(queue_size)
469 return sock 500 return sock
470 except error as _: 501 except error as _:
471 err = _ 502 err = _
472 if sock is not None: 503 if sock is not None:
473 sock.close() 504 sock.close()
474 505
475 if err is not None: 506 if err is not None:
476 raise err 507 raise err
477 else: 508 else:
478 raise error("getaddrinfo returns an empty list") 509 raise error("getaddrinfo returns an empty list")
LEFTRIGHT

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