Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

291
Vistas
API de Win32 con nombre de tubería, todas las instancias de tubería están ocupadas

Estoy tratando de escribir en una canalización con nombre y leer lo mismo. Considere el siguiente fragmento de código (el manejo de errores se elimina por brevedad):

 const char * pipeName = "\\\\.\\pipe\\pipe"; const char * buffWrite = "SOME TEXT"; unsigned buffLength = strlen(buffWrite); char buffRead[1024]; DWORD nWritten, nRead; HANDLE hPipe = CreateNamedPipe(pipeName, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 1024, 1024, 0, 0); HANDLE hFile = CreateFile(pipeName, GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); WriteFile(hFile, buffWrite, buffLength, &nWritten, 0); CloseHandle(hFile); //the next line fails with >>All pipe instances are busy.<< hFile = CreateFile(pipeName, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0); ReadFile(hFile, buffRead, buffLength, &nRead, 0); ...

Sin embargo, cuando intento reabrir la tubería para leer, la llamada CreateFile falla con "Todas las tuberías están ocupadas".

¿Que me estoy perdiendo aqui?

EDITAR. Mirar a escondidas funciona bien, es decir

 DWORD nRead, nTotal, nLeft; PeekNamedPipe(hPipe, buffRead, buffLength, &nRead, &nTotal, &nLeft);

devuelve los datos escritos correctamente.

OBSERVACIÓN. Esta es una prueba de concepto para algo más grande. No habrá nuevos subprocesos ni procesos involucrados.

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

La razón por la que obtiene ese código de error específico es que solo creó una instancia de la canalización con nombre y ya la usó. (Puede crear una nueva instancia llamando a CreateNamedPipe por segunda vez, o puede reutilizar una instancia existente llamando a DisconnectNamedPipe ).

Sin embargo, según su comentario, creo que desea que la llamada a ReadFile recupere los datos escritos por la llamada a WriteFile, es decir, desea la misma instancia de la canalización, no una nueva.

Para hacer eso, no abra un nuevo mango. Utilice el identificador existente, hPipe .

(Tenga en cuenta que cada instancia de tubería tiene dos extremos: un extremo del servidor y un extremo del cliente. El identificador de CreateNamedPipe siempre está en el extremo del servidor, y el identificador de CreateFile siempre está en el extremo del cliente. Los datos escritos en el extremo del servidor solo pueden ser leer desde el extremo del cliente, y viceversa.)

over 4 years ago · Santiago Trujillo Denunciar

0

Está tratando de usar una tubería con nombre como una especie de búfer: el cliente se conecta a él, coloca algunos datos, luego se desconecta, luego otro cliente se conecta y recupera estos datos. Este es un enfoque no válido, la tubería con nombre es solo eso: una tubería , tiene dos lados: el lado del servidor y el lado del cliente , el servidor y el cliente podrían comunicarse a través de él. Escenario habitual de uso de tuberías:

  1. El servidor crea una tubería con nombre usando la función CreateNamedPipe ;
  2. El servidor comienza a esperar las conexiones del cliente utilizando el método ConnectNamedPipe ;
  3. El cliente crea su lado de la tubería usando la llamada a la API CreateFile ;
  4. El servidor y el cliente se comunican mediante ReadFile/WriteFile ;
  5. La tubería se cierra con DisconnectNamedPipe y podría reactivarse nuevamente con ConnectNamedPipe .

Puede ver un ejemplo completo en MSDN aquí .

over 4 years ago · Santiago Trujillo Denunciar

0

Es porque ya se han abierto ambos extremos del tubo (*)...

Primero se abrió con la llamada CreatePipe, el otro fue con la primera llamada CreateFile. No debe intentar abrir una vez más la tubería, simplemente lea del MANGO hPipe:

 const char * pipeName = "\\\\.\\pipe\\pipe"; const char * buffWrite = "SOME TEXT"; unsigned buffLength = strlen(buffWrite); char buffRead[1024]; DWORD nWritten, nRead; HANDLE hPipe = CreateNamedPipe(pipeName, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 1024, 1024, 0, 0); HANDLE hFile = CreateFile(pipeName, GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); WriteFile(hFile, buffWrite, buffLength, &nWritten, 0); CloseHandle(hFile); ReadFile(hPipe, buffRead, buffLength, &nRead, 0); // nRead=9, buffRead="SOME TEXT" ...

(*) Sí especificó PIPE_UNLIMITED_INSTANCES para el parámetro nMaxInstances en la llamada CreateNamedPipe , pero como nunca llamó a ConnectNamedPipe para crear otros puntos finales, solo se permitió un CreateFile .

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda