idTCPServer在没有客户端活动的情况下向idTCPClient发送消息

idTCPServer sending message to idTCPClient without client activity

本文关键字:idTCPClient 消息 情况下 客户端 活动 idTCPServer      更新时间:2023-10-16

我使用的是Embarcadero C++Builder,我知道如何打开连接并等待服务器端的答复(客户端可以打开连接、发送消息和读取服务器发送的消息,直到连接关闭)。

客户端:

IdTCPClient1->Connect();
IdTCPClient1->Socket->WriteLn("message from client");
ShowMessage(IdTCPClient1->Socket->ReadLn());
IdTCPClient1->Disconnect();

服务器端:

ShowMessage(AContext->Connection->Socket->ReadLn());    
AContext->Connection->Socket->WriteLn("Message from server");
AContext->Connection->Disconnect();

现在,如果客户端在客户端打开连接,就可以交换消息,但我需要服务器向所有用户发送消息,这意味着客户端不知道何时打开连接。我想我正在寻找一些等待服务器消息的事件。我发现的所有例子都是在Delphi中,而不是C++中。此外,当每个客户端第一次连接时,我制作了一个vector<TIdContext*>来保存所有连接,这很好。

以下是如何从TIdTCPServer向所有连接的客户端发送消息的示例:

TIdContext *MyContext;
TList *ClientsList = IdTCPServer1->Contexts->LockList();
try {
    for (int i = 0; i < ClientsList->Count; i++) {
        MyContext = (TIdContext*) ClientsList->Items[i];
        MyContext->Connection->IOHandler->WriteLn("Message for all the clients");
    }
__finally {
    IdTCPServer1->Contexts->UnlockList();
}

你说

这意味着客户端将不知道何时打开连接。我想我正在寻找一些等待服务器消息的事件。

如果您想保留单个TCP连接,保持其打开状态并监视消息,那么上面的答案中有非常好的选项。

评论中提到的另一个选项是(也)建立UDP连接。在每个"客户端"上,创建一个iDUDPServer,该服务器侦听特定端口(与TCP连接不同的端口)。在"服务器"上,创建一个TIdUDPClient注意这里的术语差异,您将在您称之为TCP客户端的设备上安装UDPServer,反之亦然

使用此功能从服务器向您的"客户端"发送UDP消息。您将在(客户端的)IdUDPServer OnUDPRead事件中捕获该消息。

如果你的所有客户端都在同一个网段上,你可以使用UDP广播向所有监听的客户端发送一条消息。如果没有,请使用每个客户端的IP地址向其发送消息。

您的问题之一是缺少C++示例。对不起,我无法帮助编写C++代码。以下是伪代码/过程,您必须管理语言语法:

在您的"客户"上,

  1. 创建一个TIdUDPServer(把它放在一个表单上,它必须可以监听)。

  2. 将DefaultPort设置为侦听端口(如果愿意,可以设置其他选项)

  3. 为IdUDPServerUDPRead分配事件代码(AThread:TIdUDPListenerThread;AData:TArray;A绑定:TIdSocketHandle)。传入数据在AData中。如果你愿意的话,你可以通过查看ABinding.PeerIP来确认来源的IP

在您的"服务器"上

  1. 创建TIdUPDClient。

  2. 通过以下方式将您的消息发送到特定IP:

    a: 设置IdUDPClient.Host(目标)

    b: 设置IdUDPClient.Port(目标)

    c: IdUDPClient.Send(msg)

    或者,你可以在你的网段上向所有人广播:

    a: IdUDPClient.广播(消息,目标端口)

  3. "msg"将作为AData参数在IdUDPServerUDPRead事件中显示在客户端上。

此选项可能稍微复杂一些,因为涉及两个消息路径,但它不要求客户端打开与服务器的TCP连接,也不涉及为入站消息设置监视循环。事实上,如果客户端不知道要连接,它可以用来公布服务器的位置。此UDP通信是对现有TCP连接的附加,因此这些连接保持不变。