Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Windows事件一次由一个客户端接收_C++_Windows_Events_Ipc - Fatal编程技术网

C++ Windows事件一次由一个客户端接收

C++ Windows事件一次由一个客户端接收,c++,windows,events,ipc,C++,Windows,Events,Ipc,我有一个小程序(server.exe)每秒发送一个Windows事件,还有另一个程序(client.exe)等待这个事件 如果我只有一个客户机,它可以正常工作,但是当我启动多个客户机时,只有一个客户机接收下一个事件。我需要通知所有客户每个事件。我想不出如何修复我的程序 服务器发送事件如下: auto handle = CreateEvent(nullptr, FALSE, FALSE, "SERVER_HEARTBEAT"); SetEvent(handle) start "cmd /c "s

我有一个小程序(server.exe)每秒发送一个Windows事件,还有另一个程序(client.exe)等待这个事件

如果我只有一个客户机,它可以正常工作,但是当我启动多个客户机时,只有一个客户机接收下一个事件。我需要通知所有客户每个事件。我想不出如何修复我的程序

服务器发送事件如下:

auto handle = CreateEvent(nullptr, FALSE, FALSE, "SERVER_HEARTBEAT");
SetEvent(handle)
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
  ...
客户端收到如下事件

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);  
输出显示明显随机分布在客户端之间的事件:

auto handle = CreateEvent(nullptr, FALSE, FALSE, "SERVER_HEARTBEAT");
SetEvent(handle)
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构建)

#包括
#包括
int main(int argc,char*argv[])
{

std::cout下面是基于Harry Johnston的评论的最终解决方案,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;
}
#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;
}
#包括
#包括
#包括
#定义MAX_客户端20
int main(int argc,char*argv[])
{

std::您是否创建了自动重置事件。自动重置事件就是这样工作的。在您的评论之后,我将手动重置事件的第二个参数设置为FALSE,但它没有修复它(仍然有一个客户端接收到该事件)。您知道为什么吗?这里的更改是:auto handle=CreateEvent(nullptr,TRUE,FALSE,“服务器\u心跳”);您也可以在客户端中使用
CreateEvent
而不是
OpenEvent
。只有第一次调用
CreateEvent
才能实际创建事件。另一次调用-open已经存在。您没有修复客户端代码来创建通知事件(手动重置)。并且看起来像是先运行客户端,再运行服务器。如果切换到手动重置事件,则需要使用PulseEvent而不是SetEvent-除此之外。好的,唯一合理的简单解决方案是为每个客户端设置一个单独的事件对象。(如果客户端偶尔错过心跳是可以接受的,则PulseEvent可能是正常的。)谢谢大家,您的评论让我了解了自动重置的工作原理,以及创建尽可能多的事件的解决方案。如果有人需要最终解决方案,我将发布最终解决方案。再次感谢。