web-dev-qa-db-fra.com

Indy TCP Client / Serveur avec le client agissant en tant que serveur

Comment les TIdTCPClient et TIdTCPServer d'Indy peuvent-ils être utilisés 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" (attend les commandes et les exécute).

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

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

19
jpfollenius

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

Un TIdTCPServer établit uniquement la connexion. Vous devrez implémenter le reste. Ainsi, la séquence d'envoi et de réception réelle peut être 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 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, au 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 taper ce qui suit:

telnet 127.0.0.1 8080

Voici la sortie:

Quel est votre nom?

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 jusqu'à ce qu'il y ait des données. C'est la magie derrière tout cela.

18
Marcus Adams

Si vos commandes sont de nature textuelle, jetez un œil au composant TIdCmdTCPClient, il est spécialement 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
Remy Lebeau

Lorsque le client se connecte au serveur, le serveur a 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 à l'IP ou mieux encore à un ID de session généré, puis référencez cette connexion en fonction de ces critères, vous pouvez ensuite demander au serveur d'envoyer des commandes ou des messages ad hoc au client.

J'espère que cela t'aides!

5
LaKraven

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

4
Gronfi

Le composant client Indy Telnet (TIdTelnet dans le dossier Protocoles) est un très bon point de départ pour implémenter le côté client à l'aide d'un thread, en écoutant les messages du serveur.

Le client Telnet Indy se connecte au serveur Telnet et utilise n seul socket pour écrire et lire les données. La lecture se produit dans un fil d'écoute.

Cette conception peut facilement être adaptée pour créer un logiciel de messagerie distribué comme le chat, etc., et montre également à quel point le protocole peut être découplé de la couche réseau à l'aide de sockets de blocage.

3
mjn