python asyncio如何使用一个套接字监听ipv4和ipv6

时间:2017-08-27 17:58:34

标签: python-3.x python-asyncio

我想在python中使用asyncio.start_server的套接字中监听ipv4和ipv6,现在我给这个函数一个元组,但实际上它使用2个套接字来监听。

我的朋友告诉我听'::'可以用C语言在套接字中监听ipv4和ipv6,我该如何处理python asyncio

if __name__ == '__main__':
    #logging.info('start holosocket local')
    parser = argparse.ArgumentParser(description='holosocket local')
    parser.add_argument('-c', '--config', help='config file')
    args = parser.parse_args()
    if args.config:
        with open(args.config, 'r') as f:
            config = json.load(f)

    SERVER = config['server']
    SERVER_PORT = config['server_port']
    PORT = config['local_port']
    KEY = config['password']
    AUTH = config['auth_addr']

    loop = asyncio.get_event_loop()
    relay_loop = asyncio.get_event_loop()
    coro = asyncio.start_server(handle, (SERVER, '::'), SERVER_PORT, loop=loop)
    server = loop.run_until_complete(coro)

    try:
        loop.run_forever()

    except KeyboardInterrupt:
        server.close()
        loop.run_until_complete(server.wait_closed())
        loop.close()

1 个答案:

答案 0 :(得分:0)

在Linux上,您需要禁用IPV6_V6ONLY选项。但是,如果您不提供自己的套接字,则默认情况下在内核asyncio disables it explicitly中启用双堆栈。所以你需要创建ipv6套接字并传递它而不是host, port

import asyncio
import os
import socket


async def handle_echo(reader, writer):
    data = await reader.read(100)
    message = data.decode()
    addr = writer.get_extra_info('peername')
    print("Received %r from %r" % (message, addr))

    print("Send: %r" % message)
    writer.write(data)
    await writer.drain()

    print("Close the client socket")
    writer.close()


sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
sock.bind(('::', 7777))


loop = asyncio.get_event_loop()
coro = asyncio.start_server(handle_echo, sock=sock, loop=loop)
server = loop.run_until_complete(coro)

print('Serving on {}'.format(server.sockets[0].getsockname()))
try:
    loop.run_forever()
except KeyboardInterrupt:
    pass

一个简单的测试还显示了一个带有ipv4地址的警告,前缀为::ffff:

$ python3 test_server.py 
Serving on ('::', 7777, 0, 0)
Received 'A\r\n' from ('::1', 59954, 0, 0)
Send: 'A\r\n'
Close the client socket
Received 'B\r\n' from ('::1', 59956, 0, 0)
Send: 'B\r\n'
Close the client socket
Received 'C\r\n' from ('::ffff:127.0.0.1', 35800, 0, 0)
Send: 'C\r\n'
Close the client socket

您可以在维基百科找到更多信息 - IPv4-mapped IPv6 addresses