2017-08-31 19 views
0

我有一个小程序(server.exe)每秒发送一个Windows事件,另一个程序(client.exe)等待这个事件。一次接收一个客户端的Windows事件

它工作正常,如果我只有一个客户端,但当我启动多个客户端时,只有其中一个接收下一个事件。我需要为每个事件通知所有客户。我无法弄清楚如何修复我的程序。

服务器发送如下事件:

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; 
} 

完整的代码for 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; 
} 
+2

的完整源代码,您创建了一个自动重置事件的完整源代码。这就是自动重置事件的工作原理。 –

+0

在您的评论之后,我将第二个参数设置为FALSE以进行手动重置事件,但它没有修复它(仍然有一个客户端收到该事件)。你知道为什么吗?这里改变:auto handle = CreateEvent(nullptr,TRUE,FALSE,“SERVER_HEARTBEAT”); –

+1

您也可以在客户端使用'CreateEvent'代替'OpenEvent'。只有先调用CreateEvent实际创建事件。另一个电话 - 已经打开。您不修复客户端代码以创建通知事件(手动重置)。看起来像你在服务器之前运行客户端。 – RbMm

回答

1

根据评论的最终解决方案低于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; 
} 
相关问题