2012-06-07 13 views
6

Todavía me estoy acostumbrando a Indy, ya que es un sistema de socket de múltiples hilos con grandes capacidades. Una de las cosas más importantes que he visto es cómo un servidor de conexión puede tener una serie de enlaces diferentes. Por ejemplo, podría tener 3 enlaces para 3 puertos en la misma dirección IP. Estoy usando Indy 10 en Delphi XE2.¿Utiliza los enlaces múltiples de Indy Server como sockets separados?

Estoy re-construcción de un sistema antiguo de la mina que utiliza los TServerSocket pasado de moda y TClientSocket componentes de ScktComps y volver a hacerlo con Indy TIdTCPServer y TIdTCPClient. El antiguo sistema en realidad consiste en 3 sockets de servidor/cliente completamente diferentes en cada extremo, cada socket tiene un propósito distinto y funciona en conjunto, similar a como FTP usa un socket para datos binarios y el otro socket para comandos.

¿Es posible imitar tres sockets de servidor/cliente separados dentro del mismo componente utilizando estos enlaces? Sería genial si pudiera declarar solo un socket de servidor con 3 puertos enlazados, y lo mismo en el cliente, conectado a 3 puertos diferentes en el servidor. Todo lo que me gustaría hacer es eliminar la necesidad de crear 3 componentes de socket/servidor separados y combinarlos en uno solo.

Respuesta

12

Sí, puede usar un solo TIdTCPServer para administrar varios puertos a la vez. Sin embargo, en el lado del cliente, aún necesita 3 componentes distintos de cliente para conectarse a los diferentes puertos.

Cree 3 entradas en la colección TIdTCPServer.Bindings, una para cada IP/puerto local que desee escuchar, donde la propiedad TIdSocketHandle.Port sería el equivalente de la propiedad TServerSocket.Port. TServerSocket no admite de forma nativa el enlace a una dirección IP específica (aunque se puede hacer con algún trabajo manual), pero la propiedad TIdSocketHandle.IP se usa para ese fin, donde una cadena en blanco es equivalente a INADDR_ANY.

En el TIdCPServer.OnConnect, TIdCPServer.OnDisconnect y TIdCPServer.OnExecute eventos, se pueden utilizar los TIdContext.Binding.IP y TIdContext.Binding.Port propiedades para diferenciar el que la unión del zócalo llamando está conectado.

Un uso común de esto es para admitir clientes SSL y no SSL en diferentes puertos, como para protocolos como POP3 y SMTP que admiten SSL/TLS implícitos y explícitos en puertos diferentes. TIdHTTPServer hace esto para soportar urls HTTP y HTTPS en un único servidor (puede usar el TIdHTTPServer.OnQuerySSLPort para personalizar qué puertos usan SSL/TLS versus no).

Por ejemplo:

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

impresionante, preguntando cada puerto está utilizando su propio hilo, o más probablemente todos 3 en el mismo hilo contexto? –

+1

Cada entrada en la colección 'Bindings' se ejecuta en su propio hilo aceptando las conexiones entrantes en su puerto respectivo. Cada conexión de cliente aceptada se ejecuta también en su propio hilo. Por lo tanto, si tiene 3 entradas 'Vinculaciones' y 3 clientes conectados, es decir, 6 hilos en ejecución. –

+0

Perfecto, eso es exactamente lo que quería. –

Cuestiones relacionadas