2011-10-10 27 views
0

我必须为普通的TCP服务器提供一个SSL前端,所以我正在制作一个“泵”应用程序,它将提供到外部的SSL连接,而原始服务器可以保持原状。Indy SSL到普通套接字泵

我想使用Indy组件来支持我的SSL需求,但我似乎无法从SSL端口获取任何数据。我分配给TIdTCPServer.OnExecute以下事件处理程序:

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 =服务器端(我试图添加SSL的TCP服务器的客户端)。

现在,我知道它需要清理,做1ms等待并不漂亮,但在我可以攻击该问题之前,我想接收一些数据。

我的ReadBytes都没有被调用。当我使用cs.Readable()时,我只得到true一次,但我仍然无法阅读。

我该怎么做一个泵?为什么我没有获取数据?

+0

我想通了我的问题:我的SSL端口工作在PassThrough模式。我不知道我必须自己在OnConnect处理程序中设置它。 – DDS

+0

然后你必须使用Indy 10。在Indy 9和更早的版本中,即使在任何数据交换之前,服务器端SSL IOHandler都会强制所有接受的连接进行加密(PassThrough = False)。这阻止了诸如混合的SSL /非SSL客户端,STARTTLS风格的命令等等。在Indy 10中,服务器端SSL IOHandler现在接受未加密的新连接(PassThrough = True),以便您可以选择哪些客户端使用SSL以及何时使用SSL激活SSL。 –

回答

4

尝试直接使用TIdMappedPortTCP组件代替TIdTCPServerTIdMappedPortTCP处理在客户端和另一台服务器之间传递数据的所有工作。默认情况下,即使与TIdMappedPortTCP的入站连接已加密,到第二台服务器的出站连接也不会加密。

+0

我需要检查数据。根据收到的数据,端口将转发到少数几台服务器中的一台。它不只是一个直泵。在连接到客户端之前,我必须“窥视”。除此之外,这将是一个很好的方法。我会看看TIdMappedPortTCP组件的源代码,看看我应该怎么做。我正在考虑使用winsock选择自己,因为我不知道在Indy中如何做到这一点。但我假设我会在'TIdMappedPortTCP'的源代码中找到答案。谢谢!我通过Indy代码看到你的名字。干得不错! – DDS

+1

如果您只需要“查看”连接的第一个字节,您可以在OnConnect事件中执行此操作,然后动态调整TIdMappedPortTCP连接后的TIdTCPClient的Host/Post事件处理程序退出。 –