Question Indy TCP Client / Serveur avec le client agissant comme serveur


Comment peut Indy TIdTCPClient et TIdTCPServer être utilisé dans le scénario suivant:

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

Le client initie la connexion, mais agit comme un "serveur" (en attente de commandes et de leur exécution).

le OnExecute approche de TIdTCPServer ne fonctionne pas bien dans ce cas (du moins je ne le fais pas bien fonctionner). Comment pourrais-je faire ça?

J'espère que la question est suffisamment claire.


18
2017-12-07 12:48


origine


Réponses:


Rien ne vous empêche de le faire avec le composant TIdTCPServer d'Indy.

Un TIdTCPServer configure uniquement la connexion. Vous devrez mettre en œuvre le reste. La séquence de l'envoi et de la réception peut donc correspondre à ce que vous voulez.

Placez ce code dans l'événement OnExecute de votre composant 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;

Voici comment vous pouvez configurer le TIdTCPServer très simplement:

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

Cela indique au serveur d'écouter uniquement l'adresse de bouclage, sur le port 8080. Cela empêche toute personne extérieure à votre ordinateur de s'y connecter.

Ensuite, pour connecter votre client, vous pouvez accéder à une invite de commande Windows et tapez ce qui suit:

telnet 127.0.0.1 8080

Voici la sortie:

Comment vous appelez-vous?

Marcus

Bonjour Marcus.

Voulez-vous jouer à un jeu?

Connexion à l'hôte perdue.

Vous n'avez pas de telnet? Voici comment installer le client telnet sur Vista et 7.

Ou avec un client TIdTCP, vous pouvez le faire:

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;

Une chose importante à noter ici est que les instructions ReadLn attendent que des données soient disponibles. C'est la magie derrière tout ça.


17
2017-12-07 15:20



Si vos commandes sont de nature textuelle, consultez le TIdCmdTCPClient composant, il est spécifiquement conçu pour les situations où le serveur envoie des commandes au lieu du client. Le serveur peut utiliser TIdContext.Connection.IOHandler.WriteLn() ou TIdContext.Connection.IOHandler.SendCmd() pour envoyer les commandes.


7
2017-12-07 18:03



Lorsque le client se connecte au serveur, le serveur dispose d’un événement OnConnect avec un AContext: TIdContext paramètre.

Une propriété de ceci est AContext.Connection, que vous pouvez stocker en dehors de cet événement (par exemple, dans un tableau). Si vous l'associez avec l'IP ou mieux encore un ID de session généré, puis référencez cette Connexion par ce critère, vous pouvez alors demander au serveur d'envoyer des commandes ou des messages ad hoc au client.

J'espère que cela t'aides!


5
2017-12-07 13:32



normalement, le client et le serveur ont un thread qui lit les télégrammes entrants et envoie des télégrammes en attente ... mais ce type de protocole (envoi / réception, quand et quoi) dépend de l'application.


4
2017-12-07 14:08



Le composant client Indy Telnet (TIdTelnet dans le dossier Protocols) constitue un très bon point de départ pour savoir comment le client peut être implémenté à l'aide d'un thread.

Le client Indy telnet se connecte au serveur telnet et utilise une seule prise écrire et lire des données. La lecture se passe dans un fil d’écoute.

Cette conception peut facilement être adaptée pour créer des logiciels de messagerie distribués tels que le chat, etc., et montre également la facilité avec laquelle le protocole peut être découplé de la couche réseau en utilisant des sockets de blocage.


3
2017-12-07 16:54



Avec Indy, ce n'est pas possible par conception:
Indy ne prend en charge que les communications lancées par le client, ce qui signifie que le serveur ne peut envoyer une réponse aux demandes du client.
Le moyen le plus simple (mais pas le plus intelligent) d’obtenir ce que vous voulez est d’utiliser un processus de tirage. Contrôlé par une minuterie, le client demande au serveur s’il ya une nouvelle commande. Bien sûr, cela entraînera beaucoup de trafic et dépendra de votre temps d'attente.
Sinon, vous pouvez utiliser une autre bibliothèque comme ICS (http://www.overbyte.be/eng/products/ics.html)


-3
2017-12-07 14:06