#delphi #ssl #indy
#delphi #ssl #indy
Вопрос:
Я должен предоставить интерфейс SSL для обычного TCP-сервера, поэтому я создаю приложение «pump», которое обеспечит SSL-соединение с внешней средой, в то время как исходный сервер может оставаться простым.
Я пытаюсь использовать компоненты Indy для поддержки своих потребностей в SSL, но, похоже, я не могу получить какие-либо данные с SSL-порта. Я назначил TIdTCPServer.Выполняем следующий обработчик событий:
procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var
c:TIdTCPClient;
cs,ss:TIdIOHandler;
b:TBytes;
begin
c:=TIdTCPClient.Create(Self);
try
c.Host:='127.0.0.1';
c.Port:=60675;
c.ConnectTimeout:=500;
c.Connect;
ss:=c.IOHandler;
cs:=AContext.Connection.IOHandler;
while (cs.Connected) and (ss.Connected) do
begin
if cs.CheckForDataOnSource(1) then
begin
try
cs.ReadBytes(b,1,False);
except on e:Exception do
Memo1.Lines.Add(e.Message); //BAD out of Thread context
end;
if Length(b)>0 then
ss.Write(b);
end;
if ss.CheckForDataOnSource(1) then
begin
ss.ReadBytes(b,1,False);
if Length(b)>0 then
cs.Write(b);
end;
end;
finally
c.Free;
end;
end;
К TCP-серверу подключен обработчик SSL. Я сделал то же самое на обычном HTTP-сервере, и он работал нормально, поэтому я предполагаю, что проблема не в моей настройке SSL.
cs = Клиентская сторона (серверный сокет) и ss = Серверная сторона (клиент для TCP-сервера, к которому я пытаюсь добавить SSL).
Теперь я знаю, что он нуждается в очистке, и выполнение ожидания в 1 мс не очень приятно, но прежде чем я смогу решить эту проблему, я хотел бы получить некоторые данные.
Ни один из моих readBytes не вызывается. Когда я использовал cs.Readable()
, я получаю true
только один раз, но я все еще не мог читать.
Что я могу сделать, чтобы создать перекачку? Почему я не получаю данные?
Комментарии:
1. Я разобрался со своей проблемой: мой SSL-порт работал в режиме сквозной передачи. Я не знал, что мне нужно было установить это самостоятельно в обработчике OnConnect.
2. Тогда вы, должно быть, используете Indy 10. В Indy 9 и более ранних версиях серверный SSL IOHandler принудительно шифровал все принятые соединения (PASSSTHROUGH = False) еще до обмена любыми данными. Это предотвратило такие вещи, как смешанные клиенты SSL / не-SSL, команды в стиле STARTTLS и т.д. В Indy 10 серверный SSL IOHandler теперь принимает новые соединения в незашифрованном виде (Passhrough = True), поэтому вы можете выбрать, какие клиенты используют SSL и когда активировать SSL.
Ответ №1:
Попробуйте использовать TIdMappedPortTCP
компонент вместо TIdTCPServer
напрямую. TIdMappedPortTCP
выполняет всю работу по передаче данных взад и вперед между клиентом и другим сервером. По умолчанию исходящее соединение со вторым сервером не зашифровано, даже если входящее соединение с TIdMappedPortTCP
зашифровано.
Комментарии:
1. Мне нужно проверить данные. Порт перенаправляется на один из нескольких серверов, в зависимости от полученных данных. Это не просто прямая перекачка. Я должен «заглянуть» перед подключением к клиенту. Кроме того, это был бы отличный способ сделать это. Я посмотрю на исходный код
TIdMappedPortTCP
компонента и посмотрю, как я должен это делать. Я думал об использовании winsock select сам, потому что я не знаю точно, как это сделать в Indy. Но я предполагаю, что найду этот ответ в его источникеTIdMappedPortTCP
. Спасибо! Я вижу ваше имя по всему коду Indy. Отличная работа!2. Если вам нужно только «просмотреть» первые байты соединения, вы можете сделать это в
OnConnect
событии, а затем динамически настроитьHost
/Post
того, сTIdTCPClient
которымTIdMappedPortTCP
соединяется после завершения работы обработчика событий.