Indy TCP Client / Server,客户端充当服务器 [英] Indy TCP Client/Server with the client acting as a server

查看:188
本文介绍了Indy TCP Client / Server,客户端充当服务器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在以下情况下使用Indy的 TIdTCPClient TIdTCPServer

 客户端----------启动连接----------->服务器
...
客户端< ---------------命令-------------------服务器
客户端----------------响应----------------->服务器
...
客户端< ---------------命令-------------------服务器
客户端----------------响应----------------->服务器

客户端启动连接,但作为服务器 (等待命令并执行它们)。



OnExecute 方法 TIdTCPServer 无法正常工作在这种情况下(至少我没有得到正常工作)。我该怎么做?



我希望这个问题足够清楚。

解决方案>

没有任何东西阻止你使用Indy的TIdTCPServer组件。



TIdTCPServer只设置连接。你需要实现其余的。因此,实际发送和接收的顺序可以是任何您想要的。



将此代码放在TIdTCPServer组件的OnExecute事件中:

  var 
sName:String;
begin
//在连接后立即向客户端发送命令
AContext.Connection.Socket.WriteLn('你叫什么名字?
//从客户端接收响应
sName:= AContext.Connection.Socket.ReadLn;
//向客户端发送响应
AContext.Connection.Socket.WriteLn('Hello,'+ sName +'。');
AContext.Connection.Socket.WriteLn('你想玩游戏吗?');
//我们完成了我们的会话
AContext.Connection.Disconnect;
结束

以下是您可以简单地设置TIdTCPServer的方法:

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

这告诉服务器仅在端口8080上监听环回地址。您的计算机连接到它。



然后,要连接您的客户端,可以转到Windows命令提示符并键入以下内容:

  telnet 127.0.0.1 8080 

这是输出:


你叫什么名字?



Marcus



您好,Marcus。



你想玩游戏吗?

连接到主机丢失。


没有telnet?以下是在Vista和7上安装telnet客户端的方法。



或使用TIdTCP客户端,您可以执行以下操作:

  var 
sPrompt:String;
sResponse:String;
begin
//设置端口连接到
IdTCPClient1.Port:= 8080;
//设置主机连接到
IdTCPClient1.Host:='127.0.0.1';
//现在实际连接
IdTCPClient1.Connect;
//从服务器中读取提示文本
sPrompt:= IdTCPClient1.Socket.ReadLn;
//显示给用户并要求用户响应
sResponse:= InputBox('Prompt',sPrompt,'');
//将用户的响应发送回服务器
IdTCPClient1.Socket.WriteLn(sResponse);
//向用户显示服务器的最终消息
ShowMessage(IdTCPClient1.Socket.AllData);
结束

这里要注意的一个重要事情是ReadLn语句等到有数据。这是所有这些的魔力。


How can Indy's TIdTCPClient and TIdTCPServer be used in the following scenario:

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

The client initiates the connection, but acts as a "server" (waiting for commands and executing them).

The OnExecute approach of TIdTCPServer does not work well in this case (at least I am not getting it to work well). How could I do this?

I hope the question is clear enough.

解决方案

There is nothing preventing you from doing this with Indy's TIdTCPServer component.

A TIdTCPServer only sets up the connection. You'll need to implement the rest. So the sequence of the actual sending and receiving can be whatever you want.

Put this code in your TIdTCPServer component's OnExecute event:

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;

Here's how you can setup the TIdTCPServer really simply:

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

This tells the server to listen on the loopback address only, at port 8080. This prevents anyone outside of your computer from connecting to it.

Then, to connect your client, you can go to a Windows command prompt and type the following:

telnet 127.0.0.1 8080

Here's the output:

What is your name?

Marcus

Hello, Marcus.

Would you like to play a game?

Connection to host lost.

Don't have telnet? Here's how to install telnet client on Vista and 7.

Or with a TIdTCP Client, you can do this:

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;

An important thing to note here is that the ReadLn statements wait until there is data. That's the magic behind it all.

这篇关于Indy TCP Client / Server,客户端充当服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆