C 扩展windows命名管道以处理客户端信息

C 扩展windows命名管道以处理客户端信息,c,windows,driver,named-pipes,C,Windows,Driver,Named Pipes,处理和处理来自命名管道的数据 我正在尝试实现一个服务提供商来连接硬件设备。 请就我实现一个健壮系统的方法提出一些建议 提到的是提出的要求 从其他EXE进程接收数据 处理接收到的Q信息,并在客户端响应通道中发送响应信息 异步将某些故障的信息发送到客户端响应通道 实施上述制度: 已选择2个命名管道(ClntcommandRecv和ClntRespSend)。进程间(IPC)的bcz ClntcommandRecv管道将用作“使用重叠“I/O”的命名管道服务器” ClntRespSend管道将用于发送

处理和处理来自命名管道的数据

我正在尝试实现一个服务提供商来连接硬件设备。 请就我实现一个健壮系统的方法提出一些建议

提到的是提出的要求

  • 从其他EXE进程接收数据
  • 处理接收到的Q信息,并在客户端响应通道中发送响应信息
  • 异步将某些故障的信息发送到客户端响应通道
  • 实施上述制度:

  • 已选择2个命名管道(ClntcommandRecv和ClntRespSend)。进程间(IPC)的bcz
  • ClntcommandRecv管道将用作“使用重叠“I/O”的命名管道服务器”
  • ClntRespSend管道将用于发送处理后的信息
  • ClntRespSend还需要将所有异步消息从服务提供者发送到连接的应用程序
  • 从这里开始,我的实现是直截了当的

    使用文档中的“使用重叠I/O的命名管道服务器”,我将能够处理多个客户端连接请求,并使用单个线程处理其数据。 在init上,系统将创建一个线程来保存客户端ClntRespSend管道的连接实例

  • 因为,它要求设备以异步方式将其故障告知连接的客户端。 是否建议系统对“WaitForMultipleObjects”或 我们可以在n超时后读取文件超时计数吗?我们可以检查健康信息吗

  • 但是,我一直在寻找同步我的clntressend和ClntcommandRecv(MAPPIN)的最佳方法。 需要获取连接进程的进程id。由于系统是在MINGW-WIN32下开发的,服务器将无法使用(GetNamedPipeClientProcessId)直接获取进程id。 需要在获取客户端连接时形成消息结构

  • 这是我试图扩展的代码:

    #include <windows.h>
    #include <stdio.h>
    #include <tchar.h>
    //#include <strsafe.h>
    
    //#include <glib.h>
    
    #define CONNECTING_STATE 0
    #define READING_STATE 1
    #define WRITING_STATE 2
    #define INSTANCES 4
    #define PIPE_TIMEOUT 5000
    #define BUFSIZE 4096
    
    typedef struct
    {
       OVERLAPPED oOverlap;
       HANDLE hPipeInst;
       TCHAR chRequest[BUFSIZE];
       DWORD cbRead;
       TCHAR chReply[BUFSIZE];
       DWORD cbToWrite;
       DWORD dwState;
       BOOL fPendingIO;
       int processId;
    } PIPEINST, *LPPIPEINST;
    
    
    typedef struct
    {
    char appName[256];
    int processId;
    }PIPEHANDSHAKE;
    
    
    
    VOID DisconnectAndReconnect(DWORD);
    BOOL ConnectToNewClient(HANDLE, LPOVERLAPPED);
    VOID GetAnswerToRequest(LPPIPEINST);
    
    PIPEINST Pipe[INSTANCES];
    HANDLE hEvents[INSTANCES];
    
    HANDLE responsePipeHandle[INSTANCES];
    
    
    DWORD WINAPI InstanceThread(LPVOID);
    
    HANDLE hPipeHandles[10];
    PULONG  s;
    
    LPTSTR lpszPipename = TEXT("\\\\.\\pipe\\mynamedpipe");
    LPTSTR lpszResponsePipe = TEXT("\\\\.\\pipe\\mynamedpipe1");
    
    
    //GHashTable* hash;
    
    int responsePipeConnectionHandler(VOID)
    {
       BOOL   fConnected = FALSE;
       DWORD  dwThreadId = 0;
       HANDLE hPipe = INVALID_HANDLE_VALUE, hThread = NULL;
       int cbBytesRead;
       INT threadCount=0;
       //hash = g_hash_table_new(g_str_hash, g_str_equal);
       char bufferSize[512];
       for (;;)
       {
          _tprintf( TEXT("\nPipe Server: Main thread awaiting client connection on %s\n"), lpszResponsePipe);
          hPipe = CreateNamedPipe(
                  lpszResponsePipe,             // pipe name
              PIPE_ACCESS_DUPLEX,       // read/write access
              PIPE_TYPE_MESSAGE |       // message type pipe
              PIPE_READMODE_MESSAGE |   // message-read mode
              PIPE_WAIT,                // blocking mode
              PIPE_UNLIMITED_INSTANCES, // max. instances
              BUFSIZE,                  // output buffer size
              BUFSIZE,                  // input buffer size
              0,                        // client time-out
              NULL);                    // default security attribute
    
          if (hPipe == INVALID_HANDLE_VALUE)
          {
              _tprintf(TEXT("CreateNamedPipe failed, GLE=%d.\n"), GetLastError());
              return -1;
          }
    
          // Wait for the client to connect; if it succeeds,
          // the function returns a nonzero value. If the function
          // returns zero, GetLastError returns ERROR_PIPE_CONNECTED.
    
          fConnected = ConnectNamedPipe(hPipe, NULL) ?
             TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
    
          if(fConnected){
              PIPEHANDSHAKE processData;
              fConnected = ReadFile(
                 hPipe,        // handle to pipe
                 bufferSize,    // buffer to receive data
                 sizeof(PIPEHANDSHAKE), // size of buffer
                 &cbBytesRead, // number of bytes read
                 NULL);        // not overlapped I/O
              memset(&processData,0,sizeof(PIPEHANDSHAKE));
              memcpy(&processData,&bufferSize,sizeof(PIPEHANDSHAKE));
              printf("APP Process id: %d , app name: %s",processData.processId,processData.appName);
    
          }
    
        /*  if (fConnected)
          {
             printf("Client connected, creating a processing thread.\n");
    
             // Create a thread for this client.
             hThread = CreateThread(
                NULL,              // no security attribute
                0,                 // default stack size
                InstanceThread,    // thread proc
                (LPVOID) hPipe,    // thread parameter
                0,                 // not suspended
                &dwThreadId);      // returns thread ID
    
             if (hThread == NULL)
             {
                _tprintf(TEXT("CreateThread failed, GLE=%d.\n"), GetLastError());
                return -1;
             }
             else CloseHandle(hThread);
           }
          else
            // The client could not connect, so close the pipe.
             CloseHandle(hPipe);*/
       }
    
       return 0;
    }
    
    int _tmain(VOID)
    {
       DWORD i, dwWait, cbRet, dwErr,hThread;
       BOOL fSuccess;
       int dwThreadId;
    
    // The initial loop creates several instances of a named pipe
    // along with an event object for each instance.  An
    // overlapped ConnectNamedPipe operation is started for
    // each instance.
       // Create response pipe thread
         hThread = CreateThread(
          NULL,              // no security attribute
          0,                 // default stack size
          responsePipeConnectionHandler,    // thread proc
          NULL,    // thread parameter
          0,                 // not suspended
          &dwThreadId);      // returns thread ID
    
    
       if (hThread == NULL)
       {
           printf("Response server creation failed with %d.\n", GetLastError());
           return 0;
       }
    
    
       for (i = 0; i < INSTANCES; i++)
       {
    
       // Create an event object for this instance.
    
          hEvents[i] = CreateEvent(
             NULL,    // default security attribute
             TRUE,    // manual-reset event
             TRUE,    // initial state = signaled
             NULL);   // unnamed event object
    
          if (hEvents[i] == NULL)
          {
             printf("CreateEvent failed with %d.\n", GetLastError());
             return 0;
          }
    
          Pipe[i].oOverlap.hEvent = hEvents[i];
    
          Pipe[i].hPipeInst = CreateNamedPipe(
             lpszPipename,            // pipe name
             PIPE_ACCESS_DUPLEX |     // read/write access
             FILE_FLAG_OVERLAPPED,    // overlapped mode
             PIPE_TYPE_MESSAGE |      // message-type pipe
             PIPE_READMODE_MESSAGE |  // message-read mode
             PIPE_WAIT,               // blocking mode
             INSTANCES,               // number of instances
             BUFSIZE*sizeof(TCHAR),   // output buffer size
             BUFSIZE*sizeof(TCHAR),   // input buffer size
             PIPE_TIMEOUT,            // client time-out
             NULL);                   // default security attributes
    
          if (Pipe[i].hPipeInst == INVALID_HANDLE_VALUE)
          {
             printf("CreateNamedPipe failed with %d.\n", GetLastError());
             return 0;
          }
    
       // Call the subroutine to connect to the new client
    
          Pipe[i].fPendingIO = ConnectToNewClient(
             Pipe[i].hPipeInst,
             &Pipe[i].oOverlap);
    
          Pipe[i].dwState = Pipe[i].fPendingIO ?
             CONNECTING_STATE : // still connecting
             READING_STATE;     // ready to read
       }
    
       while (1)
       {
          dwWait = WaitForMultipleObjects(
             INSTANCES,    // number of event objects
             hEvents,      // array of event objects
             FALSE,        // does not wait for all
             INFINITE);    // waits indefinitely
    
       // dwWait shows which pipe completed the operation.
    
          i = dwWait - WAIT_OBJECT_0;  // determines which pipe
          if (i < 0 || i > (INSTANCES - 1))
          {
             printf("Index out of range.\n");
             return 0;
          }
    
       // Get the result if the operation was pending.
    
          if (Pipe[i].fPendingIO)
          {
             fSuccess = GetOverlappedResult(
                Pipe[i].hPipeInst, // handle to pipe
                &Pipe[i].oOverlap, // OVERLAPPED structure
                &cbRet,            // bytes transferred
                FALSE);            // do not wait
    
             switch (Pipe[i].dwState)
             {
             // Pending connect operation
                case CONNECTING_STATE:
                   if (! fSuccess)
                   {
                       printf("Error %d.\n", GetLastError());
                       return 0;
                   }
                   Pipe[i].dwState = READING_STATE;
                   break;
    
             // Pending read operation
                case READING_STATE:
                   if (! fSuccess || cbRet == 0)
                   {
                      DisconnectAndReconnect(i);
                      continue;
                   }
                   Pipe[i].cbRead = cbRet;
                   Pipe[i].dwState = WRITING_STATE;
                   break;
    
             // Pending write operation
                case WRITING_STATE:
                   if (! fSuccess || cbRet != Pipe[i].cbToWrite)
                   {
                      DisconnectAndReconnect(i);
                      continue;
                   }
                   Pipe[i].dwState = READING_STATE;
                   break;
    
                default:
                {
                   printf("Invalid pipe state.\n");
                   return 0;
                }
             }
          }
    
       // The pipe state determines which operation to do next.
    
          switch (Pipe[i].dwState)
          {
             case READING_STATE:
                fSuccess = ReadFile(
                   Pipe[i].hPipeInst,
                   Pipe[i].chRequest,
                   BUFSIZE*sizeof(TCHAR),
                   &Pipe[i].cbRead,
                   &Pipe[i].oOverlap);
                if (fSuccess && Pipe[i].cbRead != 0)
                {
                   Pipe[i].fPendingIO = FALSE;
                   Pipe[i].dwState = WRITING_STATE;
                   continue;
                }
                dwErr = GetLastError();
                if (! fSuccess && (dwErr == ERROR_IO_PENDING))
                {
                   Pipe[i].fPendingIO = TRUE;
                   continue;
                }
                DisconnectAndReconnect(i);
                break;
             case WRITING_STATE:
                GetAnswerToRequest(&Pipe[i]);
                fSuccess = WriteFile(
                   Pipe[i].hPipeInst,
                   Pipe[i].chReply,
                   Pipe[i].cbToWrite,
                   &cbRet,
                   &Pipe[i].oOverlap);
                if (fSuccess && cbRet == Pipe[i].cbToWrite)
                {
                   Pipe[i].fPendingIO = FALSE;
                   Pipe[i].dwState = READING_STATE;
                   continue;
                }
                dwErr = GetLastError();
                if (! fSuccess && (dwErr == ERROR_IO_PENDING))
                {
                   Pipe[i].fPendingIO = TRUE;
                   continue;
                }
                DisconnectAndReconnect(i);
                break;
    
             default:
             {
                printf("Invalid pipe state.\n");
                return 0;
             }
          }
      }
    
      return 0;
    }
    
    VOID DisconnectAndReconnect(DWORD i)
    {
      if (! DisconnectNamedPipe(Pipe[i].hPipeInst) )
       {
          printf("DisconnectNamedPipe failed with %d.\n", GetLastError());
       }
    
       Pipe[i].fPendingIO = ConnectToNewClient(
          Pipe[i].hPipeInst,
          &Pipe[i].oOverlap);
    
       Pipe[i].dwState = Pipe[i].fPendingIO ?
          CONNECTING_STATE : // still connecting
          READING_STATE;     // ready to read
    }
    
    BOOL ConnectToNewClient(HANDLE hPipe, LPOVERLAPPED lpo)
    {
       BOOL fConnected, fPendingIO = FALSE;
       fConnected = ConnectNamedPipe(hPipe, lpo);
       if (fConnected)
       {
          printf("ConnectNamedPipe failed with %d.\n", GetLastError());
          return 0;
       }
    
       switch (GetLastError())
       {
       // The overlapped connection in progress.
          case ERROR_IO_PENDING:
             fPendingIO = TRUE;
             break;
          case ERROR_PIPE_CONNECTED:
             if (SetEvent(lpo->hEvent))
                break;
          default:
          {
             printf("ConnectNamedPipe failed with %d.\n", GetLastError());
             return 0;
          }
       }
    
       return fPendingIO;
    }
    
    
    int rxProccesIdMsg(HANDLE pipe)
    {
        PIPEHANDSHAKE pipeInfo;
        CHAR bufferSize[512] = {'\0'};
        INT cbBytesRead;
        BOOL fSuccess;
          PIPEHANDSHAKE processData;
          fSuccess = ReadFile(
                  pipe,        // handle to pipe
           bufferSize,    // buffer to receive data
           sizeof(PIPEHANDSHAKE), // size of buffer
           &cbBytesRead, // number of bytes read
           NULL);        // not overlapped I/O
        memset(&processData,0,sizeof(PIPEHANDSHAKE));
        memcpy(&processData,&bufferSize,sizeof(PIPEHANDSHAKE));
    
    
        if ( (!fSuccess))
        {
            printf("Client: READ Server Pipe Failed(%d)\n",GetLastError());
            CloseHandle(pipe);
            return -1;
        }
        else
        {
            printf("Client: READ Server Pipe Success(%d)\n",GetLastError());
            printf("APP Process id: %d , app name: %s",processData.processId,processData.appName);
            //Sleep(3*100);
        }
        return processData.processId;
    }
    
    VOID GetAnswerToRequest(LPPIPEINST pipe)
    {
       _tprintf( TEXT("[%d] %s\n"), pipe->hPipeInst, pipe->chRequest);
      // StringCchCopy( pipe->chReply, BUFSIZE, TEXT("Default answer from server") );
       strncpy(pipe->chReply, "Default answer from server",BUFSIZE);
       pipe->cbToWrite = (lstrlen(pipe->chReply)+1)*sizeof(TCHAR);
    }
    
    #包括
    #包括
    #包括
    //#包括
    //#包括
    #定义连接状态0
    #定义读取状态1
    #定义写入状态2
    #定义实例4
    #定义管道超时5000
    #定义BUFSIZE 4096
    类型定义结构
    {
    重叠的卵缘;
    处理水管;
    TCHAR chRequest[BUFSIZE];
    德沃德·克莱德;
    TCHAR chReply[BUFSIZE];
    德沃德·克托维特;
    德沃德州;
    布尔·芬丁吉奥;
    int进程ID;
    }管道仪表,*LPPIPEINST;
    类型定义结构
    {
    字符appName[256];
    int进程ID;
    }握手;
    无效断开和连接(DWORD);
    BOOL ConnectToNewClient(手柄,重叠);
    无效获取应答请求(LPPIPEINST);
    PIPEINST管道[实例];
    处理事件[实例];
    HANDLE responsepehandle[实例];
    DWORD WINAPI实例线程(LPVOID);
    手柄[10];
    普隆s;
    LPTSTR lpszPipename=TEXT(“\\\.\\pipe\\mynamedpipe”);
    LPTSTR lpszresponsepie=TEXT(“\\\.\\pipe\\mynamedpipe1”);
    //GHashTable*散列;
    int ResponseEpieConnectionHandler(无效)
    {
    BOOL fConnected=FALSE;
    DWORD dwThreadId=0;
    HANDLE hPipe=INVALID\u HANDLE\u值,hThread=NULL;
    int-cbBytesRead;
    INT threadCount=0;
    //hash=g_hash_table_new(g_str_hash,g_str_equal);
    字符缓冲大小[512];
    对于(;;)
    {
    _tprintf(文本(“\n管道服务器:主线程在%s上等待客户端连接,\n”)、lpszresponsepe;
    hPipe=CreateNamedPipe(
    lpszResponsePipe,//管道名称
    管道\u访问\u双工,//读/写访问
    PIPE_TYPE_MESSAGE |//消息类型PIPE
    管道读取模式消息读取模式
    管道\u等待,//阻塞模式
    管道\无限\实例,//最大实例数
    BUFSIZE,//输出缓冲区大小
    BUFSIZE,//输入缓冲区大小
    0,//客户端超时
    NULL);//默认安全属性
    if(hPipe==无效的句柄值)
    {
    _tprintf(TEXT(“CreateNamedPipe失败,GLE=%d.\n”)、GetLastError();
    返回-1;
    }
    //等待客户端连接;如果成功,
    //函数返回一个非零值。如果
    //返回零,GetLastError返回错误\u管道\u连接。
    fConnected=ConnectNamedPipe(hPipe,NULL)?
    TRUE:(GetLastError()==错误\u管道\u已连接);
    如果(fConnected){
    管道握手处理数据;
    fConnected=ReadFile(
    hPipe,//句柄到管道
    bufferSize,//用于接收数据的缓冲区
    sizeof(PIPEHANDSHAKE),//缓冲区大小
    &cbBytesRead,//读取的字节数
    NULL);//不重叠的I/O
    memset(&processData,0,sizeof(PIPEHANDSHAKE));
    memcpy(&processData,&bufferSize,sizeof(PIPEHANDSHAKE));
    printf(“应用程序进程id:%d,应用程序名称:%s”,processData.processId,processData.appName);
    }
    /*如果(fConnected)
    {
    printf(“客户端已连接,正在创建处理线程。\n”);
    //为此客户端创建一个线程。
    hThread=CreateThread(
    NULL,//没有安全属性
    0,//默认堆栈大小
    InstanceThread,//线程进程
    (LPVOID)hPipe,//线程参数
    0,//未挂起
    &dwThreadId);//返回线程ID
    if(hThread==NULL)
    {
    _tprintf(文本(“CreateThread失败,GLE=%d.\n”)、GetLastError();
    返回-1;
    }
    else CloseHandle(hThread);
    }
    其他的
    //客户端无法连接,因此请关闭管道。
    闭柄(hPipe)*/
    }
    返回0;
    }
    内部(无效)
    {
    dwordi、dwWait、cbRet、dwErr、hThread;
    成功;
    int-dwThreadId;
    //初始循环将创建命名管道的多个实例
    //以及每个实例的事件对象
    //重叠连接命名管道opera