Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.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++ C++;未收到Windows异步IO命名管道第一条消息_C++_Windows_Winapi_Named Pipes - Fatal编程技术网

C++ C++;未收到Windows异步IO命名管道第一条消息

C++ C++;未收到Windows异步IO命名管道第一条消息,c++,windows,winapi,named-pipes,C++,Windows,Winapi,Named Pipes,修改源代码 使用重叠I/O的命名管道服务器 服务器代码如下所示: #include <windows.h> #include <stdio.h> #include <tchar.h> #include <strsafe.h> #include <iostream> #define CONNECTING_STATE 0 #define READING_STATE 1 #define INSTANCES 4 #define P

修改源代码 使用重叠I/O的命名管道服务器

服务器代码如下所示:

#include <windows.h> 
#include <stdio.h>
#include <tchar.h>
#include <strsafe.h>
#include <iostream>

#define CONNECTING_STATE 0 
#define READING_STATE 1 

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

} PIPEINST, *LPPIPEINST; 

BOOL ConnectToNewClient(HANDLE, LPOVERLAPPED); 

PIPEINST Pipe[INSTANCES]; 
HANDLE hEvents[INSTANCES]; 

int _tmain(VOID) 
{ 
DWORD i, dwWait, cbRet, dwErr; 
BOOL fSuccess; 
LPTSTR lpszPipename = TEXT("\\\\.\\pipe\\mynamedpipe"); 

for (i = 0; i < INSTANCES; i++) 
{ 

    hEvents[i] = CreateEvent( 
        NULL,    // default security attribute 
        FALSE,    // 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]; 

    DWORD dwOpenMode = PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED;

    Pipe[i].oOverlap.Offset = 0;
    Pipe[i].oOverlap.OffsetHigh = 0;

    Pipe[i].hPipeInst = CreateNamedPipe( 
        lpszPipename,           
        dwOpenMode,     
        PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,               
        INSTANCES,               
        BUFSIZE*sizeof(TCHAR),   
        BUFSIZE*sizeof(TCHAR),   
        PIPE_TIMEOUT,            
        NULL);                   

    if (Pipe[i].hPipeInst == INVALID_HANDLE_VALUE) 
    {
        printf("CreateNamedPipe failed with %d.\n", GetLastError());
        return 0;
    }

    BOOL rc = ConnectNamedPipe(Pipe[i].hPipeInst, &Pipe[i].oOverlap);                   // Overlapped ConnectNamedPipe should return FALSE.
    if (!rc && GetLastError() == ERROR_PIPE_CONNECTED) {
        std::cout<<"pipe connected setting event " << std::endl;
        rc = SetEvent(&Pipe[i].oOverlap.hEvent);

    } else if (rc || GetLastError() != ERROR_IO_PENDING) {
        std::cout<<"exiting... " << std::endl;
        rc = CloseHandle(Pipe[i].hPipeInst);
        return 0;
    }

}// for INSTANCES

    while (1) 
    { 
        dwWait = WaitForMultipleObjects( 
            INSTANCES,    // number of event objects 
            hEvents,      // array of event objects 
            FALSE,        // does not wait for all 
            INFINITE);    // waits indefinitely 

        i = dwWait - WAIT_OBJECT_0;  // determines which pipe 

        if (i < 0 || i > (INSTANCES - 1)) 
        {
            printf("Index out of range.\n"); 
            return 0;
        }

        fSuccess = GetOverlappedResult( 
            Pipe[i].hPipeInst, // handle to pipe 
            &Pipe[i].oOverlap, // OVERLAPPED structure 
            &cbRet,            // bytes transferred 
            FALSE);            // do not wait 

        std::cout<<"GetOverlappedResult " << cbRet;
        std::cout<<" success " << fSuccess;
        std::cout<<" state " << Pipe[i].dwState;
        std::cout<<" GetLastError " << GetLastError() << std::endl;


        fSuccess = ReadFile( 
            Pipe[i].hPipeInst, 
            Pipe[i].chRequest, 
            BUFSIZE*sizeof(TCHAR), 
            &Pipe[i].cbRead, 
            &Pipe[i].oOverlap); 

        if(!fSuccess)
            std::wcout<<L" Error: "<< GetLastError() <<std::endl;

        if (fSuccess && Pipe[i].cbRead != 0) 
        { 
            Pipe[i].fPendingIO = FALSE; 
            Pipe[i].dwState = READING_STATE; 
            std::wcout<<L"Message " << Pipe[i].chRequest << std::endl;
            continue; 
        } 

        dwErr = GetLastError(); 
        if (! fSuccess && (dwErr == ERROR_IO_PENDING)) 
        { 
            std::cout<<"Error IO is still pending" << std::endl;
            Pipe[i].fPendingIO = TRUE; 
            continue; 
        } 
        break;
    }

    return 0; 
} 

在服务器的读循环中,您将丢弃任何异步到达的数据

GetOverlappedResult()报告挂起的I/O操作完成后,缓冲区包含来自该操作的数据。您将忽略该数据并向同一缓冲区发出新的读取操作


获得任何消息的唯一原因是(在大多数运行中),所有四条消息都将同时写入管道的内部缓冲区。第一条消息是异步到达的,因此您会错过它,但其余三条消息已经在管道中,因此这些读取可以立即完成。

感谢Harry的回复,这非常有帮助:)
 #include <windows.h> 
 #include <stdio.h>
 #include <conio.h>
 #include <tchar.h>
 #include <string>
 #include <sstream>
 #include <time.h>
 #include <iostream>

 #define BUFSIZE 4096

int _tmain(int argc, TCHAR *argv[]) 
{ 
HANDLE hPipe; 

TCHAR  chBuf[BUFSIZE]; 
BOOL   fSuccess = FALSE; 
DWORD  cbRead, cbToWrite, cbWritten, dwMode; 
LPTSTR lpszPipename = TEXT("\\\\.\\pipe\\mynamedpipe"); 
BOOL   rc;

 do {
    hPipe = CreateFileW(lpszPipename, GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
    if (hPipe == INVALID_HANDLE_VALUE) {
      if (GetLastError() == ERROR_PIPE_BUSY) {
        // wait for the pipe to become available
        rc = WaitNamedPipeW(lpszPipename, NMPWAIT_USE_DEFAULT_WAIT);
        if (!rc) return false;
      } else {
        return false;
      }
    }
  } while (hPipe == INVALID_HANDLE_VALUE);

 dwMode = PIPE_READMODE_MESSAGE; 
   fSuccess = SetNamedPipeHandleState( 
      hPipe,    // pipe handle 
      &dwMode,  // new pipe mode 
      NULL,     // don't set maximum bytes 
      NULL);    // don't set maximum time 
   if ( ! fSuccess) 
   {
      _tprintf( TEXT("SetNamedPipeHandleState failed. GLE=%d\n"), GetLastError() ); 
      return -1;
   }

//===================================================================

while(1)
{
    std::cout<<"press a key to send " << std::endl;
    _getch();

    fSuccess = WriteFile( 
        hPipe,                  
        "A",
        1, 
        &cbWritten,             
        NULL);
 if ( ! fSuccess) 
    {
        _tprintf( TEXT("WriteFile to pipe failed. GLE=%d\n"), GetLastError()           ); 
        return -1;
    }

    fSuccess = WriteFile( 
        hPipe,                  
        "B",
        1, 
        &cbWritten,             
        NULL);
 if ( ! fSuccess) 
    {
        _tprintf( TEXT("WriteFile to pipe failed. GLE=%d\n"), GetLastError()    ); 
        return -1;
    }
    //Sleep(1000);

    fSuccess = WriteFile( 
        hPipe,                  
        "C",
        1, 
        &cbWritten,             
        NULL);

 if ( ! fSuccess) 
    {
        _tprintf( TEXT("WriteFile to pipe failed. GLE=%d\n"), GetLastError()       ); 
        return -1;
    }

    fSuccess = WriteFile( 
        hPipe,                  
        "D",
        1, 
        &cbWritten,             
        NULL);


    if ( ! fSuccess) 
    {
        _tprintf( TEXT("WriteFile to pipe failed. GLE=%d\n"), GetLastError()    ); 
        return -1;
    }
}// loop 


printf("\n<End of message, press ENTER to terminate connection and exit>");
_getch();

CloseHandle(hPipe); 

return 0; 
 GetOverlappedResult 0 success 1 state 0 GetLastErr
 or 997
 Error: 997
 Error IO is still pending
 GetOverlappedResult 1 success 1 state 0 GetLastErr
 or 997
 Message B
 GetOverlappedResult 1 success 1 state 1 GetLastErr
 or 997
 Message C
 GetOverlappedResult 1 success 1 state 1 GetLastErr
 or 997
 Message D
 GetOverlappedResult 1 success 1 state 1 GetLastErr
 or 997
 Error: 997
 Error IO is still pending