2009-08-06 24 views
6

Per qualche motivo sia l'albero maestro che lo slave non riescono, tuttavia sono riuscito a trovare qualche buon esempio su come intendevano lavorare, quindi non sono sicuro di dove ho sbagliato.C++ Utilizzo di pipe denominate Windows

Il master non esce mai da WaitForSingleObject dopo ConnectNamedPipe e lo slave lancia un'eccezione nella prima chiamata boost :: asio :: read, "In attesa di un processo per aprire l'altra estremità della pipa", che ho pensato io WaitNamedPipe aveva lo scopo di aspettare insieme a ConnectNamedPipe nel master?

master.cpp

asio::io_service ioservice; 
asio::windows::stream_handle in(ioservice); 
int main() 
{ 
    HANDLE pipe = INVALID_HANDLE_VALUE; 
    try 
    { 
     //create pipe 
     pipe = CreateNamedPipe("\\\\.\\pipe\\FLTest", 
      PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE | FILE_FLAG_OVERLAPPED, 
      PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, 
      255, 50000,50000, 0, 0); 
     if(pipe == INVALID_HANDLE_VALUE) 
     { 
      printWinError(); 
      return -1; 
     } 
     in.assign(pipe); 
     std::cout << "Created pipe" << std::endl; 
     //spawn child 
     STARTUPINFO   startInfo; 
     ZeroMemory(&startInfo, sizeof(STARTUPINFO)); 
     startInfo.cb = sizeof(STARTUPINFO); 
     PROCESS_INFORMATION procInfo; 
     ZeroMemory(&procInfo, sizeof(PROCESS_INFORMATION)); 
     if(CreateProcess(0, "slave.exe", 0,0, FALSE, CREATE_NEW_CONSOLE, 
      0, 0, &startInfo, &procInfo)) 
     { 
      std::cout << "Slave process created" << std::endl; 
     } 
     else 
     { 
      printWinError(); 
      DisconnectNamedPipe(pipe); 
      return -1; 
     } 

     OVERLAPPED overlapped = {0}; 
     overlapped.hEvent = CreateEvent(0,TRUE,FALSE,0); 
     if(ConnectNamedPipe(pipe, &overlapped) == FALSE) 
     { 
      unsigned error = GetLastError(); 
      if(error != ERROR_PIPE_CONNECTED && 
       error != ERROR_IO_PENDING) 
      { 
       printWinError(); 
       DisconnectNamedPipe(pipe); 
       return -1; 
      } 
     } 
     WaitForSingleObject(overlapped.hEvent, INFINITE); 
     CloseHandle(overlapped.hEvent); 
     std::cout << "Pipe connected" << std::endl; 

     for(int i = 0; i < 100; ++i) 
     { 
      boost::system::error_code error; 
      unsigned n = i * 5; 
      asio::write(in,asio::buffer((char*)&n, sizeof(unsigned)), 
       asio::transfer_all(), error); 
      if(error)throw boost::system::system_error(error); 
     } 
     std::cout << "Sent data" << std::endl; 

     FlushFileBuffers(pipe); 
     DisconnectNamedPipe(pipe); 
     system("pause"); 
     return 0; 
    } 
    catch(const std::exception &e) 
    { 
     std::cout << e.what() << std::endl; 
     if(pipe != INVALID_HANDLE_VALUE) 
      DisconnectNamedPipe(pipe); 
     system("pause"); 
     return -1; 
    } 
} 

slave.cpp

asio::io_service ioservice; 
asio::windows::stream_handle in(ioservice); 
int main() 
{ 
    try 
    { 
     WaitNamedPipe("\\\\.\\pipe\\FLTest", NMPWAIT_WAIT_FOREVER); 

     std::cout << "Pipe avaible" << std::endl; 
     HANDLE pipe = CreateNamedPipe("\\\\.\\pipe\\FLTest", 
      PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 
      PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, 
      255, 50000,50000,0,0); 
     if(pipe == INVALID_HANDLE_VALUE) 
     { 
      printWinError(); 
      return -1; 
     } 

     in.assign(pipe); 
     std::cout << "Pipe connected" << std::endl; 

     for(int i = 0; i < 100; ++i) 
     { 
      std::cout << "i: " << i << std::endl; 
      boost::system::error_code error; 
      unsigned n; 
      asio::read(in,asio::buffer((char*)&n,sizeof(unsigned)), 
       asio::transfer_all(), error); 
      if(error)throw boost::system::system_error(error); 
     } 
     system("pause"); 
     return 0; 
    } 
    catch(const std::exception &e) 
    { 
     std::cout << e.what() << std::endl; 
     system("pause"); 
     return -1; 
    } 
} 

Ovviamente Ive ha ottenuto qualcosa di completamente sbagliato, però io non ho trovato nulla in rete per confrontare il mio codice con.

risposta

10

Nel tuo schiavo è necessario chiamare CreateFile() per aprire il tubo, non CreateNamedPipe.

HANDLE pipe = CreateFile("\\\\.\\pipe\\FLTest",     
     GENERIC_READ | GENERIC_WRITE,    
     0,           
     NULL,          
     OPEN_EXISTING,        
     FILE_FLAG_OVERLAPPED,      
     NULL 
    );  
0

è necessario specificare la modalità del tubo nella parte server come PIPE_WAIT

Problemi correlati