Windows nombró tuberías en la práctica

Con las canalizaciones con nombre de Windows, ¿cuál es la forma correcta de usar las CreateNamedPipe , ConnectNamedPipe , DisconnectNamedPipe y CloseHandle ?

Estoy creando una aplicación de servidor que se conecta a una aplicación cliente que se conecta y desconecta a la tubería varias veces durante una sesión.

Cuando mis escrituras fallan porque el cliente se desconectó, debería llamar a DisconnectNamedPipe , CloseHandle o nada en mi identificador.

Luego, para aceptar una nueva conexión, ¿debería llamar a CreateNamedPipe y luego a ConnectNamedPipe , o simplemente a ConnectNamedPipe ?

Me gustaría mucho una explicación de los diferentes estados en que puede estar mi canalización como resultado de estas llamadas, porque no he encontrado esto en ningún otro lugar.

Información adicional:

Idioma: Python utilizando las win32pipe , win32file y win32api .

Configuraciones de tubería: WAIT, sin superposición, bytestream.

Es una buena práctica llamar a DisconnectNamedPipe luego a CloseHandle , aunque CloseHandle debería limpiar todo.

La documentación de MSDN es un poco vaga y su ejemplo de servidor es bastante básico. En cuanto a si reutiliza los mangos de tuberías, parece que es tu propia elección. La documentación para DisconnectNamedPipe parece indicar que puede reutilizar un controlador de canalización para un nuevo cliente llamando a ConnectNamedPipe nuevamente en ese controlador después de desconectarse. El rol de ConnectNamedPipe parece ser asignar un cliente de conexión a un identificador.

Asegúrese de que está limpiando las tuberías, ya que MSDN establece lo siguiente

Cada vez que se crea una canalización con nombre, el sistema crea los búferes de entrada y / o salida utilizando un grupo no paginado, que es la memoria física utilizada por el núcleo. El número de instancias de tubería (así como los objetos como subprocesos y procesos) que puede crear está limitado por el grupo no paginado disponible. Cada solicitud de lectura o escritura requiere espacio en el búfer para los datos de lectura o escritura, más espacio adicional para las estructuras de datos internas.

También me gustaría recordar lo anterior si estás creando / destruyendo muchos tubos. Supongo que sería mejor operar un grupo de controladores de tuberías si hay muchos clientes y tener algún mecanismo de crecimiento / reducción en el grupo.

He logrado lograr lo que quería. Llamo a CreateNamedPipe y CloseHandle exactamente una vez por sesión, y llamo a DisconnectNamedPipe cuando mi escritura falla, seguido de otro ConnectNamedPipe .

El truco es llamar solo a DisconnectNamedPipe cuando la tubería estaba realmente conectada. Lo llamé cada vez que intentaba conectarme “solo para estar seguro” y me daba errores extraños.

Vea también la respuesta de djgandy para más información sobre tuberías.