2012-06-07 3 views
6

Я все еще привык к Indy, будучи многопоточной системой сокета с огромными возможностями. Одна из больших вещей, которые я видел, - это то, как серверный сокет может иметь несколько разных привязок. Например, у вас может быть 3 привязки для 3 портов на одном и том же IP-адресе. Я использую Indy 10 на Delphi XE2.Использование нескольких привязок сервера Indy в виде отдельных сокетов?

Я заново строить старую систему шахты, которая использует старомодные TServerSocket и TClientSocket компоненты из ScktComps и повторно делать это с Инди TIdTCPServer и TIdTCPClient. Старая система на самом деле состоит из 3 совершенно разных серверных/клиентских сокетов на каждом конце, каждый сокет, предназначенный для определенной цели, и работает вместе - подобно тому, как FTP использует один сокет для двоичных данных и другой сокет для команд.

Возможно ли имитировать три отдельных гнезда сервера/клиента в одном компоненте с помощью этих привязок? Было бы здорово, если бы я мог объявить только один серверный сокет с 3 связанными портами и тот же на клиенте, подключенный к 3 различным портам на сервере. Все, что я хотел бы сделать, это исключить необходимость создания 3 отдельных компонентов сокета для сервера/клиента и объединить их в один.

ответ

12

Да, вы можете использовать один TIdTCPServer для управления несколькими портами за раз. Тем не менее, на стороне клиента вам все еще требуется 3 отдельных клиентских компонента для подключения к различным портам.

Создайте 3 записи в коллекции TIdTCPServer.Bindings, по одному для каждого локального IP/порта, который вы хотите прослушать, где свойство TIdSocketHandle.Port будет равнозначным свойству TServerSocket.Port. TServerSocket не поддерживает привязку к определенному IP (хотя это может быть сделано с некоторой ручной работой), но для этой цели используется свойство TIdSocketHandle.IP, где пустая строка эквивалентна INADDR_ANY.

В TIdCPServer.OnConnect, TIdCPServer.OnDisconnect и TIdCPServer.OnExecute события, вы можете использовать TIdContext.Binding.IP и TIdContext.Binding.Port свойства дифференцироваться которых связывание вызывающего сокета подключен.

Общим для этого является поддержка SSL и не-SSL-клиентов на разных портах, таких как протоколы, такие как POP3 и SMTP, которые поддерживают неявные и явные SSL/TLS на разных портах. TIdHTTPServer делает это для поддержки HTTP и HTTPS URL-адресов на одном сервере (вы можете использовать TIdHTTPServer.OnQuerySSLPort, чтобы настроить, какие порты используют SSL/TLS против нет).

Например:

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, просто интересно, это каждый порт, используя свой собственный поток или, скорее всего, все 3 в том же контексте потока? –

+1

Каждая запись в коллекции 'Bindings' работает в своем потоке, принимая входящие соединения на соответствующем порту. Каждое принятое клиентское соединение затем запускается также в своем потоке. Итак, если у вас есть 3 'Bindings' записи и 3 подключенных клиента, то есть 6 потоков. –

+0

Отлично, это именно то, что я хотел. –