2009-08-06 7 views
6

Pour une raison quelconque, le mât et l'esclave échouent, mais je pourrais trouver de bons exemples sur la façon dont ils devaient fonctionner, donc je ne sais pas où je me suis trompé. Le maître ne quitte jamais WaitForSingleObject après ConnectNamedPipe, et l'esclave lève une exception dans le premier appel boost :: asio :: read, "En attente d'un processus pour ouvrir l'autre extrémité du tube". WaitNamedPipe était destiné à attendre avec le ConnectNamedPipe dans le maître?C++ Utilisation de fenêtres nommées tubes

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

Il est évident que Ive a obtenu quelque chose de complètement tort, mais je ne pouvais pas trouver quoi que ce soit sur le net pour comparer mon code avec.

Répondre

10

Dans votre esclave, vous devez appeler CreateFile() pour ouvrir le tuyau, pas CreateNamedPipe.

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

Vous devez spécifier le mode de la conduite dans la partie serveur comme PIPE_WAIT

Questions connexes