idTCPServer在没有客户端活动的情况下向idTCPClient发送消息
idTCPServer sending message to idTCPClient without client activity
我使用的是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++代码。以下是伪代码/过程,您必须管理语言语法:
在您的"客户"上,
-
创建一个TIdUDPServer(把它放在一个表单上,它必须可以监听)。
-
将DefaultPort设置为侦听端口(如果愿意,可以设置其他选项)
- 为IdUDPServerUDPRead分配事件代码(AThread:TIdUDPListenerThread;AData:TArray;A绑定:TIdSocketHandle)。传入数据在AData中。如果你愿意的话,你可以通过查看ABinding.PeerIP来确认来源的IP
在您的"服务器"上
-
创建TIdUPDClient。
-
通过以下方式将您的消息发送到特定IP:
a: 设置IdUDPClient.Host(目标)
b: 设置IdUDPClient.Port(目标)
c: IdUDPClient.Send(msg)
或者,你可以在你的网段上向所有人广播:
a: IdUDPClient.广播(消息,目标端口)
-
"msg"将作为AData参数在IdUDPServerUDPRead事件中显示在客户端上。
此选项可能稍微复杂一些,因为涉及两个消息路径,但它不要求客户端打开与服务器的TCP连接,也不涉及为入站消息设置监视循环。事实上,如果客户端不知道要连接,它可以用来公布服务器的位置。此UDP通信是对现有TCP连接的附加,因此这些连接保持不变。
- boost::进程间消息队列引发错误
- 在线编译器中的分段C++没有打印消息
- C++错误消息*成员参考.**初学者*
- 在createdialog创建的窗口中捕获用于编辑控件的OnMouseMove消息
- 要与"if constexpr"一起使用的编译时消息(在预处理器之后)
- 如何通过参数抛出错误消息
- 从服务器传输到客户端的消息不会出现
- ROS2 动态消息模板
- C++秘密消息学校作业
- glad 导致 glfwSwapBuffers 返回错误消息
- C++入门 5 版:类消息和文件夹
- FindPackageHandleStandardArgs.cmake:137 的 CMake 错误(消息):找不到 Boost (缺少:正则表达式)(找到合适的版本"1.72.0",
- 如何处理从一个对象传递到另一个在C++中具有公共抽象类的对象的消息
- 如何接受 [ENTER] 键作为无效输入并发送错误消息
- 由于无效的 ValidateRgn() 子窗口不会收到WM_PAINT消息
- "string.h"在构建适用于iOS的qt应用程序中找不到消息
- 如何将 Firebase 与基于 Linux 的客户端应用配合使用,以便与服务器进行双向消息通信
- 重新定义预定义的 errno 错误消息 (E2BIG)
- Libmosquitto publish 不会将所有消息传递到 Azure IoT Hub
- idTCPServer在没有客户端活动的情况下向idTCPClient发送消息