扩展名为pipe的窗口以处理客户端信息

时间:2015-02-03 06:57:11

标签: c windows driver named-pipes

处理&处理来自命名管道的数据。

我正在尝试实现服务提供程序以连接硬件设备。 请求我的方法来实现一个强大的系统。

提到的是提出的要求

  1. 从其他EXE流程接收数据
  2. 处理收到的Q信息并在客户响应通道中发送响应信息。
  3. 将有关故障的信息异步发送到客户端响应通道。
  4. 实施上述系统:

    1. 在进程(IPC)之间选择2个命名管道(ClntcommandRecv& ClntRespSend).bcz
    2. ClntcommandRecv管道将用作“使用重叠的命名管道服务器”I / O“
    3. ClntRespSend管道将用于发送已处理的信息。
    4. ClntRespSend还需要将所有异步消息从服务提供商发送到连接的应用程序。
    5. 从这里我的实施是直截了当的。

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

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

      2. 但是,坚持找到同步我的ClntRespSend&的最佳方法。 ClntcommandRecv(MAPPIN)。 需要获取连接进程的进程ID。由于系统是在MINGW-WIN32下开发的 - 服务器无法通过使用(GetNamedPipeClientProcessId)直接获取进程ID。 需要在获取客户端连接时形成消息结构。

      3. 这是我试图扩展的代码:

        #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 个答案:

没有答案