def create_socket(family, bindaddr, port): sockaddr = ('', port) if bindaddr is not None: gai_family = 0 if family == socket.AF_INET6 else family addrs = socket.getaddrinfo(bindaddr, port, gai_family) family, socktype, proto, canonname, sockaddr = addrs[0] try: sock = socket.socket(family, socket.SOCK_STREAM) if family == socket.AF_INET6 and socket.has_ipv6: # Windows needs this socket option set to listen on both IPV4 and # IPV6. However, IPPROTO_IPV6 is missing from the socket module on Windows. # Since the value is likely to never change, just include it here. IPPROTO_IPV6 = 41 sock.setsockopt(IPPROTO_IPV6, socket.IPV6_V6ONLY, 0) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) _core._mark_non_inheritable(sock.fileno()) sock.bind(sockaddr) return sock except socket.error as e: print(family, sockaddr) # Fall back to IPv4 if family == socket.AF_INET6 and e.args[0] in (97, 10047): return create_socket(socket.AF_INET, bindaddr, port) raise
def spawn_local(clientclass=_core.Client, **kw): '''Create a private server instance and connect to it.''' global _local_id csock, ssock = socketpair() _core._mark_non_inheritable(csock.fileno()) spawn_runner_process(ssock, 'local:%d' % _local_id, b'', kw, (csock,)) ssock.close() rc = clientclass(b'') rc.set_socket(csock, 'local:%d' % _local_id) _local_id += 1 return rc