2010-04-14 18 views
17

Estoy tratando de implementar canalizaciones con nombre en C++, pero o mi lector no está leyendo nada, o mi escritor no está escribiendo nada (o ambos). Aquí está mi lector:C++: implementando canalizaciones con nombre utilizando la API de Win32

int main() 
{ 
    HANDLE pipe = CreateFile(GetPipeName(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); 

    char data[1024]; 
    DWORD numRead = 1; 

    while (numRead >= 0) 
    { 
     ReadFile(pipe, data, 1024, &numRead, NULL); 

     if (numRead > 0) 
      cout << data; 
    } 

    return 0; 
} 

LPCWSTR GetPipeName() 
{ 
    return L"\\\\.\\pipe\\LogPipe"; 
} 

Y aquí está mi escritor:

int main() 
{ 
    HANDLE pipe = CreateFile(GetPipeName(), GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); 

    string message = "Hi"; 
    WriteFile(pipe, message.c_str(), message.length() + 1, NULL, NULL); 

    return 0; 
} 

LPCWSTR GetPipeName() 
{ 
    return L"\\\\.\\pipe\\LogPipe"; 
} 

¿Eso se ve bien? numRead en el lector siempre es 0, por alguna razón, y no lee nada más que 1024 -54 (algún personaje I raro).

Solución:

Reader (servidor):

while (true) 
{ 
    HANDLE pipe = CreateNamedPipe(GetPipeName(), PIPE_ACCESS_INBOUND | PIPE_ACCESS_OUTBOUND , PIPE_WAIT, 1, 1024, 1024, 120 * 1000, NULL); 

    if (pipe == INVALID_HANDLE_VALUE) 
    { 
     cout << "Error: " << GetLastError(); 
    } 

    char data[1024]; 
    DWORD numRead; 

    ConnectNamedPipe(pipe, NULL); 

    ReadFile(pipe, data, 1024, &numRead, NULL); 

    if (numRead > 0) 
     cout << data << endl; 

    CloseHandle(pipe); 
} 

escritor (cliente):

HANDLE pipe = CreateFile(GetPipeName(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); 

if (pipe == INVALID_HANDLE_VALUE) 
{ 
    cout << "Error: " << GetLastError(); 
} 

string message = "Hi"; 

cout << message.length(); 

DWORD numWritten; 
WriteFile(pipe, message.c_str(), message.length(), &numWritten, NULL); 

return 0; 

Los bloques de servidor hasta que se consigue un cliente conectado, lee lo que el cliente escribe, y luego se prepara para una nueva conexión, ad infinitum. ¡Gracias por toda la ayuda!

+1

Debe afirmar que las asas de tubería son válidas antes de operar en ellas. En general, algo más de robustez en su código le ayudará a descubrir y depurar problemas. – fbrereto

+1

Compruebe si el resultado de ReadFile/WriteLine es 'TRUE'. Tal vez haya un error al leer/escribir, como un conducto no válido. – AndiDog

+1

compruebe HANDLE si es válido o no, luego use GetLastError y la salida de WriteFile – Andrey

Respuesta

12

Debe usar CreateNamedPipe() para crear el extremo del servidor de un conducto con nombre. Asegúrese de especificar un tamaño de búfer distinto de cero, cero (documentado por MSDN como "uso del tamaño de búfer predeterminado del sistema") no funciona. MSDN tiene decent samples para un servidor & de cliente multiproceso.

11

Un cliente de canalización con nombre puede abrir el conducto con nombre con CreateFile - pero el servidor de canalización con nombre necesita utilizar CreateNamedPipe para crear el conducto con nombre. Después de crear el conducto con nombre, el servidor usa ConnectNamedPipe para esperar a que se conecte un cliente. Solo después de el cliente se ha conectado en caso de que el servidor haga un bloqueo de lectura como su llamada al ReadFile.

Cuestiones relacionadas