我想在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()
答案 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。