Anonymous
Я не могу установить HTTPS-соединение с программой
Сообщение
Anonymous » 14 янв 2025, 15:31
Есть программа, которая генерирует XML-файлы с результатами соревнований, не могу разобраться в коде этой программы. В программе есть возможность выводить данные через HTTP-запросы. Я написал мини-сервер Tornado Python для получения этих данных. С обычным HTTP-соединением разобрался, и мне удалось установить соединение и получить данные, а с HTTPS — нет. Получается, что в обычном HTTP программа выступает в роли HTTP-клиента и отправляет данные на сервер. Сначала я отправил запрос опций, и после ответа сервера соединение устанавливается и отправляются почтовые запросы. Но в случае с HTTPS я не знаю, что происходит. Простое добавление оболочки TSL не работает. Потому что после успешного рукопожатия сразу разрывается соединение с сервером. После разрыва соединения программа пытается подключиться с другого порта. И я так понимаю, что даже первый запрос опций не успевает отправить. Интерфейс программы не содержит никаких данных о подключении, кроме включения и отключения режима HTTPS.
При успешном подключении приложение выглядит следующим образом.
Документации к нему нет. программа.
HTTP-соединение
Вот как выглядит мой код для успешного HTTP-соединения< /p>
Код: Выделить всё
import tornado.ioloop
import tornado.web
class MainHandler(tornado.web.RequestHandler):
def log_request(self):
print("----- HTTP Request -----")
print(f"Method: {self.request.method}")
print(f"URI: {self.request.uri}")
print(f"Headers: \n{self.request.headers}")
if self.request.body:
print(f"Body: {self.request.body.decode('utf-8')}")
print(f"protocol: {self.request.protocol}")
print("------------------------")
print(f"Request: {self.request}")
print("------------------------")
def post(self):
self.log_request()
if len(self.request.body) > MAX_MESSAGE_SIZE:
self.set_status(413)
self.write("Payload Too Large")
return
data = self.request.body.decode("utf-8")
print(f"Received POST data: {data}")
self.set_status(200)
self.write("POST data received")
def get(self):
self.set_status(201)
def options(self):
self.log_request()
self.set_status(200)
self.set_header("Cache-Control","no-cache")
self.set_header("X-HOVTP-Environment","Test")
self.set_header("X-HOVTP-Last-Serial-Number","12345")
self.set_header("X-HOVTP-Keep-Alive-Interval","20")
class sMainHandler(tornado.web.RequestHandler):
def log_request(self):
print("----- HTTP Request -----")
print(f"Method: {self.request.method}")
print(f"URI: {self.request.uri}")
print(f"Headers: \n{self.request.headers}")
if self.request.body:
print(f"Body: {self.request.body.decode('utf-8')}")
print(f"protocol: {self.request.protocol}")
print("------------------------")
print(f"Request: {self.request}")
print("------------------------")
def options(self):
self.log_request()
self.set_status(200)
self.set_header("Cache-Control", "no-store, no-cache")
self.set_header("Connection", "keep-alive")
def make_app():
return tornado.web.Application([
(r"/HOVTP/", MainHandler),
#(r".*", sMainHandler),
])
if __name__ == "__main__":
app = make_app()
app.listen(443)
print("Server is running on http://localhost:8888")
tornado.ioloop.IOLoop.current().start()
А теперь HTTPS-соединение
Вот мой самый рабочий код для подключения на данный момент
Код: Выделить всё
import tornado.ioloop
import tornado.web
from tornado import http1connection
from tornado.tcpserver import TCPServer
from tornado.iostream import StreamClosedError
import socket, ssl
import logging
import asyncio
import functools
def get_ssl_context():
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
ssl_context.verify_mode = ssl.VerifyMode.CERT_NONE
ssl_context.load_cert_chain("cert/certificate.crt", "cert/privateKey.key")
ssl_context.keylog_filename = "keys.txt"
ssl_context.options |= ssl.OP_NO_COMPRESSION
ssl_context.options |= ssl.OP_NO_TICKET
ssl_context.options |= ssl.OP_ENABLE_MIDDLEBOX_COMPAT
ssl_context.options |= ssl.OP_SINGLE_ECDH_USE
return ssl_context
class EchoServer(TCPServer):
async def handle_stream(self, stream, address):
while True:
try:
data = await stream.read_until(b"\n")
await stream.write(data)
except StreamClosedError:
print(stream.closed(), address)
break
if __name__ == "__main__":
try:
async def main():
server = EchoServer(get_ssl_context())
server.listen(443)
await asyncio.Event().wait()
asyncio.run(main())
except ssl.SSLError:
print(ssl.SSLError)
А вот вывод Wireshark
Код: Выделить всё
No. Time Source Destination Protocol Length Info
25 2.696257 127.0.0.1 127.0.0.1 TCP 56 52908 → 443 [SYN] Seq=0 Win=65535 Len=0 MSS=65495 WS=256 SACK_PERM
Frame 25: 56 bytes on wire (448 bits), 56 bytes captured (448 bits) on interface \Device\NPF_Loopback, id 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 52908, Dst Port: 443, Seq: 0, Len: 0
No. Time Source Destination Protocol Length Info
26 2.696292 127.0.0.1 127.0.0.1 TCP 56 443 → 52908 [SYN, ACK] Seq=0 Ack=1 Win=65535 Len=0 MSS=65495 WS=256 SACK_PERM
Frame 26: 56 bytes on wire (448 bits), 56 bytes captured (448 bits) on interface \Device\NPF_Loopback, id 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 443, Dst Port: 52908, Seq: 0, Ack: 1, Len: 0
No. Time Source Destination Protocol Length Info
27 2.696315 127.0.0.1 127.0.0.1 TCP 44 52908 → 443 [ACK] Seq=1 Ack=1 Win=2161152 Len=0
Frame 27: 44 bytes on wire (352 bits), 44 bytes captured (352 bits) on interface \Device\NPF_Loopback, id 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 52908, Dst Port: 443, Seq: 1, Ack: 1, Len: 0
No. Time Source Destination Protocol Length Info
28 2.696401 127.0.0.1 127.0.0.1 HTTP 302 OPTIONS /HOVTP/ HTTP/1.1
Frame 28: 302 bytes on wire (2416 bits), 302 bytes captured (2416 bits) on interface \Device\NPF_Loopback, id 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 52908, Dst Port: 443, Seq: 1, Ack: 1, Len: 258
Hypertext Transfer Protocol
No. Time Source Destination Protocol Length Info
30 2.696418 127.0.0.1 127.0.0.1 TCP 44 443 → 52908 [ACK] Seq=1 Ack=259 Win=2160896 Len=0
Frame 30: 44 bytes on wire (352 bits), 44 bytes captured (352 bits) on interface \Device\NPF_Loopback, id 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 443, Dst Port: 52908, Seq: 1, Ack: 259, Len: 0
No. Time Source Destination Protocol Length Info
36 2.698030 127.0.0.1 127.0.0.1 HTTP 308 HTTP/1.1 200 OK
Frame 36: 308 bytes on wire (2464 bits), 308 bytes captured (2464 bits) on interface \Device\NPF_Loopback, id 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 443, Dst Port: 52908, Seq: 1, Ack: 259, Len: 264
Hypertext Transfer Protocol
No. Time Source Destination Protocol Length Info
37 2.698047 127.0.0.1 127.0.0.1 TCP 44 52908 → 443 [ACK] Seq=259 Ack=265 Win=2160896 Len=0
Frame 37: 44 bytes on wire (352 bits), 44 bytes captured (352 bits) on interface \Device\NPF_Loopback, id 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 52908, Dst Port: 443, Seq: 259, Ack: 265, Len: 0
No. Time Source Destination Protocol Length Info
62 7.711112 127.0.0.1 127.0.0.1 HTTP 302 OPTIONS /HOVTP/ HTTP/1.1
Frame 62: 302 bytes on wire (2416 bits), 302 bytes captured (2416 bits) on interface \Device\NPF_Loopback, id 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 52908, Dst Port: 443, Seq: 259, Ack: 265, Len: 258
Hypertext Transfer Protocol
No. Time Source Destination Protocol Length Info
63 7.711134 127.0.0.1 127.0.0.1 TCP 44 443 → 52908 [ACK] Seq=265 Ack=517 Win=2160640 Len=0
Frame 63: 44 bytes on wire (352 bits), 44 bytes captured (352 bits) on interface \Device\NPF_Loopback, id 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 443, Dst Port: 52908, Seq: 265, Ack: 517, Len: 0
No. Time Source Destination Protocol Length Info
66 7.712553 127.0.0.1 127.0.0.1 HTTP 308 HTTP/1.1 200 OK
Frame 66: 308 bytes on wire (2464 bits), 308 bytes captured (2464 bits) on interface \Device\NPF_Loopback, id 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 443, Dst Port: 52908, Seq: 265, Ack: 517, Len: 264
Hypertext Transfer Protocol
No. Time Source Destination Protocol Length Info
67 7.712590 127.0.0.1 127.0.0.1 TCP 44 52908 → 443 [ACK] Seq=517 Ack=529 Win=2160640 Len=0
Frame 67: 44 bytes on wire (352 bits), 44 bytes captured (352 bits) on interface \Device\NPF_Loopback, id 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 52908, Dst Port: 443, Seq: 517, Ack: 529, Len: 0
Я тоже пытался построить такой сервер
Код: Выделить всё
async def handle_connection(connection, address):
io_loop = tornado.ioloop.IOLoop.current()
print(f"Connect from {address[0]}:{address[1]}")
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
ssl_context.load_cert_chain("cert/certificate.crt", "cert/privateKey.key")
ssl_context.keylog_filename = "keys.txt"
ssl_context.options |= ssl.OP_NO_COMPRESSION
ssl_context.options |= ssl.OP_NO_TICKET
stream = tornado.iostream.IOStream(connection)
stream.set_nodelay(True)
stream = await stream.start_tls(True,ssl_context)
stream = await stream.wait_for_handshake()
print(stream.socket.session, stream.socket.session.id)
sessionList.append(stream)
def new_con(sock,fd,events):
print("Current connections:")
for i in sessionList:
print(i, i.closed())
while True:
try:
conn, fromaddr = sock.accept()
except BlockingIOError:
print("Close connection")
return
io_loop = tornado.ioloop.IOLoop.current()
io_loop.spawn_callback(handle_connection, conn, fromaddr)
async def main():
print("Listen for connection.")
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.setblocking(0)
sock.bind(("127.0.0.1", 443))
sock.listen(5)
io_loop = tornado.ioloop.IOLoop.current()
callback = functools.partial(new_con, sock)
io_loop.add_handler(sock.fileno(), callback, io_loop.READ)
await asyncio.Event().wait()
if __name__ == "__main__":
try:
asyncio.run(main())
except ssl.SSLError:
print(ssl.SSLError)
Вот попытка подключения из Wireshark
Здесь я сохранил 3 попытки подключения, чтобы показать, как сервер меняет порт
Подробнее здесь:
https://stackoverflow.com/questions/793 ... he-program
1736857914
Anonymous
Есть программа, которая генерирует XML-файлы с результатами соревнований, не могу разобраться в коде этой программы. В программе есть возможность выводить данные через HTTP-запросы. Я написал мини-сервер Tornado Python для получения этих данных. С обычным HTTP-соединением разобрался, и мне удалось установить соединение и получить данные, а с HTTPS — нет. Получается, что в обычном HTTP программа выступает в роли HTTP-клиента и отправляет данные на сервер. Сначала я отправил запрос опций, и после ответа сервера соединение устанавливается и отправляются почтовые запросы. Но в случае с HTTPS я не знаю, что происходит. Простое добавление оболочки TSL не работает. Потому что после успешного рукопожатия сразу разрывается соединение с сервером. После разрыва соединения программа пытается подключиться с другого порта. И я так понимаю, что даже первый запрос опций не успевает отправить. Интерфейс программы не содержит никаких данных о подключении, кроме включения и отключения режима HTTPS. При успешном подключении приложение выглядит следующим образом. [b]Документации к нему нет. программа. :D[/b] [b]HTTP-соединение[/b] Вот как выглядит мой код для успешного HTTP-соединения< /p> [code]import tornado.ioloop import tornado.web class MainHandler(tornado.web.RequestHandler): def log_request(self): print("----- HTTP Request -----") print(f"Method: {self.request.method}") print(f"URI: {self.request.uri}") print(f"Headers: \n{self.request.headers}") if self.request.body: print(f"Body: {self.request.body.decode('utf-8')}") print(f"protocol: {self.request.protocol}") print("------------------------") print(f"Request: {self.request}") print("------------------------") def post(self): self.log_request() if len(self.request.body) > MAX_MESSAGE_SIZE: self.set_status(413) self.write("Payload Too Large") return data = self.request.body.decode("utf-8") print(f"Received POST data: {data}") self.set_status(200) self.write("POST data received") def get(self): self.set_status(201) def options(self): self.log_request() self.set_status(200) self.set_header("Cache-Control","no-cache") self.set_header("X-HOVTP-Environment","Test") self.set_header("X-HOVTP-Last-Serial-Number","12345") self.set_header("X-HOVTP-Keep-Alive-Interval","20") class sMainHandler(tornado.web.RequestHandler): def log_request(self): print("----- HTTP Request -----") print(f"Method: {self.request.method}") print(f"URI: {self.request.uri}") print(f"Headers: \n{self.request.headers}") if self.request.body: print(f"Body: {self.request.body.decode('utf-8')}") print(f"protocol: {self.request.protocol}") print("------------------------") print(f"Request: {self.request}") print("------------------------") def options(self): self.log_request() self.set_status(200) self.set_header("Cache-Control", "no-store, no-cache") self.set_header("Connection", "keep-alive") def make_app(): return tornado.web.Application([ (r"/HOVTP/", MainHandler), #(r".*", sMainHandler), ]) if __name__ == "__main__": app = make_app() app.listen(443) print("Server is running on http://localhost:8888") tornado.ioloop.IOLoop.current().start() [/code] [b]А теперь HTTPS-соединение[/b] Вот мой самый рабочий код для подключения на данный момент [code]import tornado.ioloop import tornado.web from tornado import http1connection from tornado.tcpserver import TCPServer from tornado.iostream import StreamClosedError import socket, ssl import logging import asyncio import functools def get_ssl_context(): ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) ssl_context.verify_mode = ssl.VerifyMode.CERT_NONE ssl_context.load_cert_chain("cert/certificate.crt", "cert/privateKey.key") ssl_context.keylog_filename = "keys.txt" ssl_context.options |= ssl.OP_NO_COMPRESSION ssl_context.options |= ssl.OP_NO_TICKET ssl_context.options |= ssl.OP_ENABLE_MIDDLEBOX_COMPAT ssl_context.options |= ssl.OP_SINGLE_ECDH_USE return ssl_context class EchoServer(TCPServer): async def handle_stream(self, stream, address): while True: try: data = await stream.read_until(b"\n") await stream.write(data) except StreamClosedError: print(stream.closed(), address) break if __name__ == "__main__": try: async def main(): server = EchoServer(get_ssl_context()) server.listen(443) await asyncio.Event().wait() asyncio.run(main()) except ssl.SSLError: print(ssl.SSLError) [/code] А вот вывод Wireshark [code]No. Time Source Destination Protocol Length Info 25 2.696257 127.0.0.1 127.0.0.1 TCP 56 52908 → 443 [SYN] Seq=0 Win=65535 Len=0 MSS=65495 WS=256 SACK_PERM Frame 25: 56 bytes on wire (448 bits), 56 bytes captured (448 bits) on interface \Device\NPF_Loopback, id 0 Null/Loopback Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1 Transmission Control Protocol, Src Port: 52908, Dst Port: 443, Seq: 0, Len: 0 No. Time Source Destination Protocol Length Info 26 2.696292 127.0.0.1 127.0.0.1 TCP 56 443 → 52908 [SYN, ACK] Seq=0 Ack=1 Win=65535 Len=0 MSS=65495 WS=256 SACK_PERM Frame 26: 56 bytes on wire (448 bits), 56 bytes captured (448 bits) on interface \Device\NPF_Loopback, id 0 Null/Loopback Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1 Transmission Control Protocol, Src Port: 443, Dst Port: 52908, Seq: 0, Ack: 1, Len: 0 No. Time Source Destination Protocol Length Info 27 2.696315 127.0.0.1 127.0.0.1 TCP 44 52908 → 443 [ACK] Seq=1 Ack=1 Win=2161152 Len=0 Frame 27: 44 bytes on wire (352 bits), 44 bytes captured (352 bits) on interface \Device\NPF_Loopback, id 0 Null/Loopback Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1 Transmission Control Protocol, Src Port: 52908, Dst Port: 443, Seq: 1, Ack: 1, Len: 0 No. Time Source Destination Protocol Length Info 28 2.696401 127.0.0.1 127.0.0.1 HTTP 302 OPTIONS /HOVTP/ HTTP/1.1 Frame 28: 302 bytes on wire (2416 bits), 302 bytes captured (2416 bits) on interface \Device\NPF_Loopback, id 0 Null/Loopback Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1 Transmission Control Protocol, Src Port: 52908, Dst Port: 443, Seq: 1, Ack: 1, Len: 258 Hypertext Transfer Protocol No. Time Source Destination Protocol Length Info 30 2.696418 127.0.0.1 127.0.0.1 TCP 44 443 → 52908 [ACK] Seq=1 Ack=259 Win=2160896 Len=0 Frame 30: 44 bytes on wire (352 bits), 44 bytes captured (352 bits) on interface \Device\NPF_Loopback, id 0 Null/Loopback Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1 Transmission Control Protocol, Src Port: 443, Dst Port: 52908, Seq: 1, Ack: 259, Len: 0 No. Time Source Destination Protocol Length Info 36 2.698030 127.0.0.1 127.0.0.1 HTTP 308 HTTP/1.1 200 OK Frame 36: 308 bytes on wire (2464 bits), 308 bytes captured (2464 bits) on interface \Device\NPF_Loopback, id 0 Null/Loopback Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1 Transmission Control Protocol, Src Port: 443, Dst Port: 52908, Seq: 1, Ack: 259, Len: 264 Hypertext Transfer Protocol No. Time Source Destination Protocol Length Info 37 2.698047 127.0.0.1 127.0.0.1 TCP 44 52908 → 443 [ACK] Seq=259 Ack=265 Win=2160896 Len=0 Frame 37: 44 bytes on wire (352 bits), 44 bytes captured (352 bits) on interface \Device\NPF_Loopback, id 0 Null/Loopback Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1 Transmission Control Protocol, Src Port: 52908, Dst Port: 443, Seq: 259, Ack: 265, Len: 0 No. Time Source Destination Protocol Length Info 62 7.711112 127.0.0.1 127.0.0.1 HTTP 302 OPTIONS /HOVTP/ HTTP/1.1 Frame 62: 302 bytes on wire (2416 bits), 302 bytes captured (2416 bits) on interface \Device\NPF_Loopback, id 0 Null/Loopback Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1 Transmission Control Protocol, Src Port: 52908, Dst Port: 443, Seq: 259, Ack: 265, Len: 258 Hypertext Transfer Protocol No. Time Source Destination Protocol Length Info 63 7.711134 127.0.0.1 127.0.0.1 TCP 44 443 → 52908 [ACK] Seq=265 Ack=517 Win=2160640 Len=0 Frame 63: 44 bytes on wire (352 bits), 44 bytes captured (352 bits) on interface \Device\NPF_Loopback, id 0 Null/Loopback Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1 Transmission Control Protocol, Src Port: 443, Dst Port: 52908, Seq: 265, Ack: 517, Len: 0 No. Time Source Destination Protocol Length Info 66 7.712553 127.0.0.1 127.0.0.1 HTTP 308 HTTP/1.1 200 OK Frame 66: 308 bytes on wire (2464 bits), 308 bytes captured (2464 bits) on interface \Device\NPF_Loopback, id 0 Null/Loopback Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1 Transmission Control Protocol, Src Port: 443, Dst Port: 52908, Seq: 265, Ack: 517, Len: 264 Hypertext Transfer Protocol No. Time Source Destination Protocol Length Info 67 7.712590 127.0.0.1 127.0.0.1 TCP 44 52908 → 443 [ACK] Seq=517 Ack=529 Win=2160640 Len=0 Frame 67: 44 bytes on wire (352 bits), 44 bytes captured (352 bits) on interface \Device\NPF_Loopback, id 0 Null/Loopback Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1 Transmission Control Protocol, Src Port: 52908, Dst Port: 443, Seq: 517, Ack: 529, Len: 0 [/code] Я тоже пытался построить такой сервер [code]async def handle_connection(connection, address): io_loop = tornado.ioloop.IOLoop.current() print(f"Connect from {address[0]}:{address[1]}") ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) ssl_context.load_cert_chain("cert/certificate.crt", "cert/privateKey.key") ssl_context.keylog_filename = "keys.txt" ssl_context.options |= ssl.OP_NO_COMPRESSION ssl_context.options |= ssl.OP_NO_TICKET stream = tornado.iostream.IOStream(connection) stream.set_nodelay(True) stream = await stream.start_tls(True,ssl_context) stream = await stream.wait_for_handshake() print(stream.socket.session, stream.socket.session.id) sessionList.append(stream) def new_con(sock,fd,events): print("Current connections:") for i in sessionList: print(i, i.closed()) while True: try: conn, fromaddr = sock.accept() except BlockingIOError: print("Close connection") return io_loop = tornado.ioloop.IOLoop.current() io_loop.spawn_callback(handle_connection, conn, fromaddr) async def main(): print("Listen for connection.") sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.setblocking(0) sock.bind(("127.0.0.1", 443)) sock.listen(5) io_loop = tornado.ioloop.IOLoop.current() callback = functools.partial(new_con, sock) io_loop.add_handler(sock.fileno(), callback, io_loop.READ) await asyncio.Event().wait() if __name__ == "__main__": try: asyncio.run(main()) except ssl.SSLError: print(ssl.SSLError) [/code] Вот попытка подключения из Wireshark Здесь я сохранил 3 попытки подключения, чтобы показать, как сервер меняет порт Подробнее здесь: [url]https://stackoverflow.com/questions/79355002/i-cant-establish-a-https-connection-to-the-program[/url]