一个客户一次收到Windows事件
Windows events are received by one client at a time
我有一个小程序(server.exe)每秒发送一个Windows事件,而另一个程序(client.exe)等待此事件。
如果我只有一个客户端,则可以正常工作,但是当我启动多个客户端时,其中只有一个会收到下一个事件。我需要所有客户都会通知每个事件。我不知道如何修复我的程序。
服务器发送事件如下:
auto handle = CreateEvent(nullptr, FALSE, FALSE, "SERVER_HEARTBEAT");
SetEvent(handle)
客户端接收到下面的事件:
static HANDLE handles[1];
handles[0] = CreateEvent(nullptr, FALSE, FALSE, "SERVER_HEARTBEAT");
auto bit_no = WaitForMultipleObjectsEx(1,
static_cast<CONST HANDLE *>(handles),
TRUE,
INFINITE,
TRUE);
我有一个批处理文件可以启动4个客户端和1个服务器:
start "cmd /c "start "client.exe" 0
start "cmd /c "start "client.exe" 1
start "cmd /c "start "client.exe" 2
start "cmd /c "start "client.exe" 3
start "cmd /c "start "server.exe"
输出显示在客户端之间分布的事件显然是随机的:
SERVER> Sending the event each second...
CLIENT 3> received heartbeat
CLIENT 1> received heartbeat
CLIENT 2> received heartbeat
...
server.exe的完整代码(建立在Visual Studio 2015)
#include <windows.h>
#include <iostream>
int main(int argc, char* argv[])
{
std::cout << "SERVER> Sending the event each second..." << std::endl;
std::string line;
auto handle = CreateEvent(nullptr, FALSE, FALSE, "SERVER_HEARTBEAT");
if (handle == nullptr)
{
std::cout << "error: create event failed" << std::endl;
exit(0);
}
while (true)
{
if (!SetEvent(handle))
{
std::cout << "error: SetEvent failed" << std::endl;
}
Sleep(1000);
}
CloseHandle(handle);
return 0;
}
client.exe的完整代码(建立在Visual Studio 2015)
#include <windows.h>
#include <string>
#include <iostream>
#include <locale>
int main(int argc, char* argv[])
{
// Set the client id
if (argc != 2)
{
std::cout << "error: missing client id" << std::endl;
exit(0);
}
// Validate the client id to a be positive value
std::string input = argv[1];
std::locale loc;
auto it = begin(input);
while (it != end(input) && std::isdigit(*it, loc)) ++it;
if (it != end(input))
{
std::cout << "invalid client id specified: " << input.c_str() << std::endl;
return 1;
}
auto client_id = std::stoi(input);
if (client_id < 0)
{
std::cout << "the client id must be a positive number: " << input.c_str() << std::endl;
return 1;
}
// Initialize the client to listen the heartbeat from the DCS App Manager running on the same station
static HANDLE handles[1];
handles[0] = CreateEvent(nullptr, FALSE, FALSE, "SERVER_HEARTBEAT");
if (handles[0] == nullptr)
{
std::cout << "error: create event failed" << std::endl;
exit(0);
}
while (true)
{
auto bit_no = WaitForMultipleObjectsEx(
1, // number of handles in the handle array
static_cast<CONST HANDLE *>(handles), // pointer to the object-handle array
TRUE, // returns when the state of any one of
// the objects set to is signaled
INFINITE, // time-out interval never elapses
TRUE); // Alertable
if (bit_no == WAIT_FAILED)
{
std::cout << "error: WaitForMultipleObjects failed" << std::endl;
break;
}
std::cout << "CLIENT " << client_id << "> received heartbeat" << std::endl;
}
CloseHandle(handles[0]);
return 0;
}
在最终解决方案下方,基于 Harry Johnston 的评论,他被告知创建与最大数量的客户数量一样数量。结果,所有客户端都会定期收到服务器心跳消息。
server.exe的完整代码
#include <windows.h>
#include <iostream>
#include <string>
#define MAX_CLIENTS 20
int main(int argc, char* argv[])
{
std::cout << "SERVER> Sending the event each second..." << std::endl;
std::string line;
static HANDLE handles[MAX_CLIENTS];
for (auto client_id = 0; client_id < MAX_CLIENTS; client_id++)
{
auto eventName = std::string("SERVER_HEARTBEAT_") + std::to_string(client_id);
std::cout << "create event " << eventName << std::endl;
handles[client_id] = CreateEvent(nullptr, FALSE, FALSE, eventName.c_str());
if (handles[client_id] == nullptr)
{
std::cout << "error: create event failed" << std::endl;
exit(0);
}
}
while (true)
{
std::cout << "sending events" << std::endl;
for (auto client_id = 0; client_id < MAX_CLIENTS; client_id++)
{
if (!SetEvent(handles[client_id]))
{
std::cout << "error: SetEvent failed" << std::endl;
}
}
Sleep(1000);
}
for (auto client_id = 0; client_id < MAX_CLIENTS; client_id++)
{
CloseHandle(handles[client_id]);
}
return 0;
}
client.exe
的完整代码#include <windows.h>
#include <string>
#include <iostream>
#include <locale>
int main(int argc, char* argv[])
{
// Set the client id
if (argc != 2)
{
std::cout << "error: missing client id" << std::endl;
exit(0);
}
// Validate the client id to a be positive value
std::string input = argv[1];
std::locale loc;
auto it = begin(input);
while (it != end(input) && std::isdigit(*it, loc)) ++it;
if (it != end(input))
{
std::cout << "invalid client id specified: " << input.c_str() << std::endl;
return 1;
}
auto client_id = std::stoi(input);
if (client_id < 0)
{
std::cout << "the client id must be a positive number: " << input.c_str() << std::endl;
return 1;
}
// Initialize the client to listen the heartbeat from the DCS App Manager
// running on the same station
static HANDLE handles[1];
auto eventName = std::string("SERVER_HEARTBEAT_") + std::to_string(client_id);
std::cout << "listening for the event " << eventName << std::endl;
handles[0] = CreateEvent(nullptr, FALSE, FALSE, eventName.c_str());
if (handles[0] == nullptr)
{
std::cout << "error: create event failed" << std::endl;
exit(0);
}
while (true)
{
auto result = WaitForMultipleObjectsEx(
1, // number of handles in the handle array
static_cast<CONST HANDLE *>(handles), // pointer to the object-handle array
TRUE, // returns when the state of any one of
// the objects set to is signaled
INFINITE, // time-out interval never elapses
TRUE); // Alertable
if (result == WAIT_FAILED)
{
std::cout << "error: WaitForMultipleObjects failed" << std::endl;
break;
}
std::cout << "CLIENT " << client_id << "> received heartbeat" << std::endl;
}
CloseHandle(handles[0]);
return 0;
}
相关文章:
- Windows 进程间同步类似事件?
- 如何实现从 Windows 脚本主机到脚本的事件调度
- 具有多个 OR 的 Xpath 查询不适用于 Windows 事件
- 如何从Qt绑定到在Windows 7 / 8 / 10中连接/断开USB设备事件
- Windows 在 C++ 中锁定和解锁事件
- 如何将Windows事件日志刷新到磁盘
- 一个客户一次收到Windows事件
- 如何从Windows XP下的程序中知道或更改Windows事件日志的大小
- Windows事件在Linux中使用条件变量实现
- 从 Windows 事件唤醒 QThread
- 我可以在 QP(量子平台)活动对象中等待 Windows 事件(WaitForMultipleObjects)吗?
- 正在从Registry_TypeGroup1类获取注册表项路径(Windows事件跟踪)
- 如何调试是否设置了 Windows 事件对象
- Windows 事件日志中没有类别
- 如何在Qt中检测Windows事件
- 需要通过引用类传递Windows事件句柄的帮助
- 使用Log4cxx记录到windows事件
- 如何保持Qt小部件响应键盘和鼠标,同时处理Windows事件
- 从远程计算机(Windows XP)以编程方式检索Windows事件
- Windows事件的Boost等效