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

我正在尝试实现服务提供程序以连接硬件设备 . 请求关于我实现强大系统的方法的一些指示 .

提到的是提出的要求

  • 从其他EXE进程接收数据

  • 处理收到的Q信息并在客户响应通道中发送响应信息 .

  • 异步向客户端响应通道发送有关故障的信息 .

要实现上述系统:

  • 在进程(IPC)之间选择了2个命名管道(ClntcommandRecv&ClntRespSend).bcz

  • ClntcommandRecv管道将用作"Named Pipe Server Using Overlapped" I / O“

  • ClntRespSend管道将用于发送已处理的信息 .

  • ClntRespSend还需要将所有异步消息从服务提供者发送到连接的应用程序 .

从这里开始我的实施是直截了当的 .

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

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

  • 但是,坚持找到同步我的ClntRespSend和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);
}