简介
一般来说,RAD Studio 中的文档非常清晰,几乎每个场景都有很好的示例,在这种情况下我不知所措,文档中有以下关于 TSocket 的内容:
要将您的套接字用作服务器套接字:
- 将您的套接字绑定到本地适配器。
- 配置您的套接字以启动
- 监听传入连接。
- 接受传入连接。
- 与远程套接字交换数据:从远程套接字接收数据。
- 向远程套接字发送数据。
- 关闭插座。
现在一切都很好,但是您实际上如何做到这一点以及如何使用这些方法并将它们结合在一起。通过遵循 Microsoft MSDN 的文档,我能够获得单个连接来工作。
单连接解决方案
这是我“工作”的第一个解决方案:
program SocketServer;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils, System.Net.Socket, System.Types;
var Socket: TSocket;
begin
WriteLn('Starting Socket');
Socket := TSocket.Create(TSocketType.TCP);
Socket.Listen('127.0.0.1', '', 9006); //Very important ... second param is service
try
try
var Connection := Socket.Accept(); //Waits until you connect - seems to be blocking
while True do //All the examples have this
begin
WriteLn('Listening for data');
var Bytes := Connection.Receive(); //Many ways to do this, opted for the simplest
if StringOf(Bytes) <> '' then //Probably could have made this more optimal but it works
begin
WriteLn('Received: ' +StringOf(Bytes));
WriteLn('Sent: OK');
Connection.Send('OK');
end;
Sleep(1000); //Added this to give the processor a break
end;
finally
Socket.Free;
end;
except
On E:Exception do
begin
WriteLn('Exception happened:'+E.Message);
end;
end;
end.
如果您想处理来自单个连接的消息,该应用程序可以正常工作。我正在使用telnet进行测试,如果我连接多次似乎不起作用:
telnet localhost 9006
如果我输入一堆字符并按 Enter 键,我会得到响应。 这应该如何异步工作,或者我如何让它以异步方式工作,以便我可以接受多个连接。 在这个阶段,任何基本的解决方案/指向正确方向的点都会很棒,我可以从那里进行改进。我也不清楚连接何时应关闭或如何在不导致访问冲突或内存泄漏的情况下关闭连接。我也需要“退出”主循环,而不是无限循环的忠实拥护者......
在回答这个问题之前
提前感谢您对此问题提供任何明确的解决方案。 如果我弄清楚了这一点,我会自己回答这个问题,并欢迎就如何改进提出意见。
TSocket.Accept()
方法确实是阻塞的,它会等待直到接受新客户端,除非您为其提供Timeout
。
在此模式下,您必须在单独的线程中为客户端
TSocket
提供服务,以便 Accept()
循环可以返回等待下一个客户端(这与 Indy 的 TIdTCPServer
内部运行的模型相同)。
对于您要查找的内容,请改用
TSocket.BeginAccept()
方法,该方法异步运行。 您可以提供一个回调,当新客户端被接受时会收到通知,或者您可以收到一个可以定期轮询的 IAsyncResult
。 不管怎样,当接受操作完成后,调用TSocket.EndAccept()
来获取接受的客户端TSocket
。 然后,您可以使用 TSocket.BeginReceive()
和 TSocket.BeginSend()
方法(以及相应的 TSocket.End...()
方法)与该客户端进行异步通信。