Я использую библиотеку asyncio в Python 3.8 https://docs.python.org/3/library/asyncio.html
Я создаю сервер, и в функции обратного вызова "недавно принятое соединение" я хочу узнайте удаленный IP-адрес и порт нового клиента.
Аргументы функции обратного вызова являются одним экземпляром StreamReader и StreamWriter, используемым для чтения и записи с клиента. Есть ли простой способ найти IP-адрес и порт потоков? Обратите внимание, что я хочу сделать это как для SSL, так и для не-SSL соединений.
Здесь я создаю сервер:
async def create_server(self, new_client_cb, host, port):
srvsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
srvsocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
srvsocket.bind((host, port))
srvsocket.listen(5)
return await asyncio.start_server(new_client_cb, sock=srvsocket, start_serving=False)
Я передаю функцию обратного вызова, которая придерживается документации и принимает экземпляр StreamReader и StreamWriter.
Здесь указана функция обратного вызова. Это часть класса, отсюда и ведущий аргумент self.
async def _new_client(self, client_r, client_w):
try:
self.logger.debug("New client on incoming proxy")
dests_r = {}
dests_w = {}
for addr in self.config['addrlist']:
host, port = addr.split(':')
host = socket.gethostbyname(host)
self.logger.debug(f"Connecting to {addr}...")
r, w = await self.protocol.open_connection(host, port)
self.logger.debug(f"Connected to {addr}")
dests_r[addr] = r
dests_w[addr] = w
done, pending = await asyncio.wait(
[self._tunnel(list(dests_r.values()), [client_w]), self._tunnel([client_r], list(dests_w.values()))],
return_when=asyncio.FIRST_EXCEPTION
)
for result in done:
if result.exception():
raise result.exception()
except Exception as e:
self.logger.error(f"Caught exception: {str(e)}")
traceback.print_exc()
В этой функции многое происходит, касающееся других аспектов моего приложения. Я думаю, что мой вопрос в конечном итоге сводится к следующему: как мне узнать удаленный адрес и порт, связанный с новым клиентом, с учетом этих входных данных, StreamReader и StreamWriter? Я изучаю классы транспорта Asyncio: https://docs.python.org/3/library/asyncio-protocol.html, но, возможно, другие могут указать мне правильное направление.
По классам транспорта Asyncio я вижу, что они позволяют вам запрашивать " дополнительная информация через функцию get_extra_info (str), например:
client_r._transport.get_extra_info('socket')
Хорошо, это работает для незашифрованных (не-SSL) трафиков c. Но я не могу запросить сокет на зашифрованном транспорте. Я могу получить только объект SSL:
https://docs.python.org/3/library/ssl.html#ssl .SSLObject
Этот объект предоставляет атрибут «имя_сервера», который даст мне имя хоста / IP, который использовался для подключения, поэтому на данный момент мне просто нужен порт.