Непонятно из вашего описания, использует ли TServerSocket
SSL на порту 8040 или нет. Это имеет большое значение в том, как вы установили TIdMappedPortTCP
. Однако из вашего описания у вас есть MappedPort
и DefaultPort
права собственности, по крайней мере, назад. DefaultPort
порт, который прослушивает TIdMappedPortTCP
, поэтому она должна быть 8041. MappedPort
порт, который подключается к TIdMappedPortTCP
, поэтому он должен быть 8040.
Это не имеет ничего общего иметь в незашифрованном виде и шифрованных соединений на одном порту. Большинство протоколов используют отдельные порты. Это дело здесь? Является ли порт 8040 незашифрованным, а порт 8041 зашифрован?
Если вы хотите TIdMappedPortTCP
принимать зашифрованные и незашифрованные клиентов на отдельных портах, необходимо добавить 2 записи в TIdMappedPortTCP.Bindings
коллекции, по одному для каждого порта, а не использовать DefaultPort
свойство вообще. В событии TIdMappedPortTCP.OnConnect
вы можете определить, к какому порту подключен клиент, а затем настроить AThread.OutboundClient
, прежде чем он подключится к TServerSocket
.
Неразумно, чтобы незашифрованные и зашифрованные клиенты подключались к одному и тому же порту. В этом случае вам нужно обнюхать первые несколько байтов, чтобы узнать, отправляет ли клиент SSL-квитирование или нет, а затем действовать соответствующим образом. Вместо этого проще просто использовать отдельные порты. Однако некоторые протоколы позволяют клиенту подключаться к незашифрованному порту, а затем отправлять команду для активации шифрования при необходимости. В этом случае вам понадобится только 1 порт в TIdMappedPortTCP
, поэтому вы можете определить 1 Binding
или использовать DefaultPort
.
TIdMappedPortTCP
предназначен, прежде всего, для прямой пересылки необработанных байтов между клиентом и целевым сервером. Если TServerSocket
использует SSL и вы хотите, чтобы клиент разговаривал с TServerSocket
, используя SSL правильно, вы не должны использовать TIdServerIOHandlerSSL
. Пусть TIdMappedPortTCP
передает сырые зашифрованные данные клиента как есть - TServerSocket
и наоборот. Они должны установить безопасную сессию друг с другом, а не с вами. Это особенно важно, если один из них выполняет проверку подлинности сверстников.
Если вам необходимо обработать зашифрованные данные, которые обмениваются между клиентом и TServerSocket
, вам необходимо расшифровать и повторно зашифровать данные при прохождении через TIdMappedPortTCP
(что означает, что вы действуете как человек, средний злоумышленник, который должен проверять проверку сверстников). Для этого вам необходимо установить отдельные сеансы SSL между клиентом и TIdMappedPortTCP
, а также между TIdMappedPortTCP
и TServerSocket
. Присвоение TIdServerIOHandlerSSL
TIdMappedPortTCP
облегчает сеанс с клиентом. Вы должны вручную настроить сеанс с TServerSocket
. Для этого вам необходимо вручную назначить новый объект TIdSSLIOHandlerSocket
объекту AThread.OutboundClient.IOHandler
в событии OnConnect
.TIdMappedPortTCP
не справится с этим для вас.
Если, однако, TServerSocket
не использует SSL, и вы используете TIdMappedPortTCP
в качестве шлюза SSL в TServerSocket
, то вы можете пропустить OutboundClient.IOHandler
задание, так как вам нужно будет только 1 SSL сессии, между TIdMappedPortTCP
и клиентом.
Теперь, с тем, что есть некоторые проблемы в Инди 9. Свойство TIdSSLIOHandlerOpenSSL.PassThrough
является значение False по умолчанию (таким образом, предполагая, шифрование изначально активно), и TIdServerIOHandlerSSL
предполагает, что каждый принял соединение клиента с использованием SSL, даже если это действительно не так. Если незашифрованный клиент подключается к TIdMappedPortTCP
с присвоенным TIdServerIOHandlerSSL
, клиент не будет обрабатываться правильно. Эти проблемы были исправлены в Indy 10. Но в Indy 9 вы не сможете обрабатывать зашифрованные и незашифрованные клиенты в том же компоненте TIdMappedPortTCP
. Если вы имеете дело только с зашифрованными клиентами, вы не столкнетесь с проблемой. В противном случае создайте компоненты 2 TIdMappedPortTCP
, один из которых прослушивает незашифрованный порт, а другой - зашифрованный порт. Они могут совместно использовать одни и те же обработчики событий. Если необходимо, вы можете использовать свойство AThread.Connection.Socket.Binding.Port
, чтобы узнать, к какому порту подключен клиент.
Я думаю, что ответ на мой вопрос здесь http://stackoverflow.com/questions/7707429/indy-ssl-to-plain-socket-pump – delphifive