2012-06-07 33 views
6

Wciąż się przyzwyczajałem do Indy, będąc wielowątkowym systemem gniazd z ogromnymi możliwościami. Jedną z największych rzeczy, które widziałem, jest to, że gniazdo serwera może mieć wiele różnych powiązań. Na przykład możesz mieć 3 wiązania dla 3 portów na tym samym adresie IP. Używam Indy 10 na Delphi XE2.Używanie wielu wiązań Indy Server jako oddzielnych gniazd?

ja ponownie budynku starej kopalni system, który wykorzystuje staroświecki TServerSocket i TClientSocket komponenty z ScktComps i ponownie robi to z Indy TIdTCPServer i TIdTCPClient. Stary system składa się właściwie z 3 zupełnie różnych gniazd serwera/klienta na każdym końcu, z każdego gniazda służącego do odrębnego celu i współpracującego - podobnie jak FTP używa jednego gniazda dla danych binarnych, a drugie dla poleceń.

Czy możliwe jest naśladowanie trzech oddzielnych gniazd serwera/klienta w ramach tego samego komponentu przy użyciu tych powiązań? Byłoby wspaniale, gdybym mógł zadeklarować tylko jedno gniazdo serwera z 3 połączonymi portami, i to samo na kliencie, podłączone do 3 różnych portów na serwerze. Wszystko, co chciałbym zrobić, to wyeliminowanie potrzeby tworzenia 3 oddzielnych komponentów gniazd serwera/klienta i łączenia ich w jedno.

Odpowiedz

12

Tak, można używać pojedynczego TIdTCPServer do zarządzania wieloma portami naraz. Po stronie klienta nadal potrzebne są 3 różne komponenty klienta do łączenia się z różnymi portami.

Tworzenie 3 wpisy w kolekcji TIdTCPServer.Bindings, po jednym dla każdej lokalnej IP/port, który chcesz nasłuchiwać, w którym nieruchomość TIdSocketHandle.Port byłby equivilent nieruchomości TServerSocket.Port. TServerSocket nie obsługuje natywnie powiązania z konkretnym adresem IP (chociaż można to zrobić za pomocą ręcznej pracy), ale do tego celu używana jest właściwość TIdSocketHandle.IP, w której pusty ciąg jest równy INADDR_ANY.

W TIdCPServer.OnConnect, TIdCPServer.OnDisconnect i TIdCPServer.OnExecute imprezy, można użyć TIdContext.Binding.IP i TIdContext.Binding.Port właściwości wiążące, które różnicują wzywającą gniazdo jest połączone.

Powszechnie używa się tego do obsługi klientów SSL i innych niż SSL na różnych portach, takich jak protokoły takie jak POP3 i SMTP, które obsługują niejawny i jawny SSL/TLS na różnych portach. TIdHTTPServer służy do obsługi adresów URL na jednym serwerze (można użyć parametru TIdHTTPServer.OnQuerySSLPort, aby dostosować, które porty korzystają z protokołu SSL/TLS, a nie z niego).

Na przykład:

procedure TForm1.StartButtonCick(Sender: TObject); 
begin 
    IdTCPServer1.Active := False; 
    IdTCPServer1.Bindings.Clear; 

    with IdTCPServer1.Bindings.Add do 
    begin 
    IP := ...; 
    Port := 2000; 
    end; 

    with IdTCPServer1.Bindings.Add do 
    begin 
    IP := ...; 
    Port := 2001; 
    end; 

    with IdTCPServer1.Bindings.Add do 
    begin 
    IP := ...; 
    Port := 2002; 
    end; 

    IdTCPServer1.Active := True; 
end; 

procedure TForm1.IdTCPServer1Execute(AContext: TIdContext); 
begin 
    case AContext.Binding.Port of 
    2000: begin 
     // do something... 
    end; 
    2001: begin 
     // do something else... 
    end; 
    2002: begin 
     // do yet something else ... 
    end; 
    end; 
end; 
+0

Awesome, po prostu zastanawiasz się każdy port za pomocą własnego wątku lub najprawdopodobniej wszystkie 3 w tym samym wątku kontekstowego? –

+1

Każdy wpis w kolekcji 'Wiązania' działa we własnym wątku przyjmującym połączenia przychodzące na odpowiednim porcie. Każde zaakceptowane połączenie klienta działa również we własnym wątku. Więc jeśli masz 3 wpisy 'Bindings' i 3 połączone klienty, to 6 wątków działa. –

+0

Doskonały, dokładnie tego chciałem. –