delphi client-server delphi-xe indy indy10

delphi - Indy TCP Client/Server con el cliente actuando como servidor



client-server delphi-xe (6)

¿Cómo se pueden TIdTCPClient y TIdTCPServer Indy en el siguiente escenario?

Client ---------- initate connection -----------> Server ... Client <---------------command------------------- Server Client ----------------response-----------------> Server ... Client <---------------command------------------- Server Client ----------------response-----------------> Server

El cliente inicia la conexión , pero actúa como un "servidor" (esperando los comandos y ejecutándolos).

El enfoque OnExecute de TIdTCPServer no funciona bien en este caso (al menos no estoy logrando que funcione bien). ¿Cómo podría hacer esto?

Espero que la pregunta sea lo suficientemente clara.


Con Indy esto no es posible por diseño:
Indy solo admite la comunicación iniciada por el cliente, lo que significa que el servidor solo puede enviar una respuesta a las solicitudes del cliente.
La forma más fácil (pero no la más inteligente) de obtener lo que desea es usar un proceso de extracción. Controlado por un temporizador, los clientes preguntan al servidor si hay un nuevo comando. Por supuesto, esto generará una gran cantidad de tráfico y, dependiendo de su intervalo de extracción, hay un retraso.
Alternativamente, podría usar otra biblioteca como ICS ( http://www.overbyte.be/eng/products/ics.html )


Cuando el cliente se conecta al servidor, el servidor tiene un evento OnConnect con un parámetro AContext: TIdContext .

Una propiedad de esto es AContext.Connection , que puede almacenar fuera de ese evento (por ejemplo, en una matriz). Si lo empareja con la IP o mejor aún con una ID de sesión generada, luego refiérase a esa Conexión según ese criterio, luego puede hacer que el servidor envíe comandos o mensajes adhoc al cliente.

¡Espero que esto ayude!


No hay nada que le impida hacer esto con el componente TIdTCPServer de Indy.

Un TIdTCPServer solo configura la conexión. Tendrás que implementar el resto. Entonces, la secuencia del envío y la recepción reales puede ser lo que quieras.

Coloque este código en el evento OnExecute de su componente TIdTCPServer:

var sName: String; begin // Send command to client immediately after connection AContext.Connection.Socket.WriteLn(''What is your name?''); // Receive response from client sName := AContext.Connection.Socket.ReadLn; // Send a response to the client AContext.Connection.Socket.WriteLn(''Hello, '' + sName + ''.''); AContext.Connection.Socket.WriteLn(''Would you like to play a game?''); // We''re done with our session AContext.Connection.Disconnect; end;

Así es como puede configurar TIdTCPServer realmente simple:

IdTCPServer1.Bindings.Clear; IdTCPServer1.Bindings.Add.SetBinding(''127.0.0.1'', 8080); IdTCPServer1.Active := True;

Esto le dice al servidor que solo escuche en la dirección de bucle invertido, en el puerto 8080. Esto evita que cualquier persona fuera de su computadora se conecte a él.

Luego, para conectar su cliente, puede ir a un símbolo del sistema de Windows y escribir lo siguiente:

telnet 127.0.0.1 8080

Aquí está el resultado:

¿Cuál es su nombre?

Marcus

Hola, Marcus.

¿Te gustaría jugar un juego?

Conexión al host perdido.

¿No tienes telnet? A continuación se explica cómo instalar el cliente de telnet en Vista y 7 .

O con un Cliente TIdTCP, puede hacer esto:

var sPrompt: String; sResponse: String; begin // Set port to connect to IdTCPClient1.Port := 8080; // Set host to connect to IdTCPClient1.Host := ''127.0.0.1''; // Now actually connect IdTCPClient1.Connect; // Read the prompt text from the server sPrompt := IdTCPClient1.Socket.ReadLn; // Show it to the user and ask the user to respond sResponse := InputBox(''Prompt'', sPrompt, ''''); // Send user''s response back to server IdTCPClient1.Socket.WriteLn(sResponse); // Show the user the server''s final message ShowMessage(IdTCPClient1.Socket.AllData); end;

Una cosa importante a tener en cuenta aquí es que las instrucciones ReadLn esperan hasta que haya datos. Esa es la magia detrás de todo.


Normalmente, el cliente y el servidor tienen un hilo que lee los telegramas entrantes y envía telegramas pendientes ... pero este tipo de protocolos (envío / recepción, cuándo y qué) dependen de la aplicación.


Si sus comandos son de naturaleza textual, eche un vistazo al componente TIdCmdTCPClient , está específicamente diseñado para situaciones en las que el servidor envía comandos en lugar del cliente. El servidor puede usar TIdContext.Connection.IOHandler.WriteLn() o TIdContext.Connection.IOHandler.SendCmd() para enviar los comandos.


Un buen punto de partida de cómo el lado del cliente puede implementarse usando un hilo, escuchando los mensajes del servidor, es el componente del cliente Indy Telnet (TIdTelnet en la carpeta Protocolos).

El cliente de telnet de Indy se conecta al servidor de telnet y usa solo un socket para escribir y leer datos. La lectura ocurre en un hilo oyente.

Este diseño se puede adaptar fácilmente para crear software de mensajería distribuida, como chat, etc., y también muestra la facilidad con la que se puede desacoplar el protocolo de la capa de red utilizando sockets de bloqueo.