2011-10-10 26 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事件處理程序退出。 –