2017-05-02 4 views
3

J'essaie d'obtenir une application C++ pour informer une application C# lorsqu'une action particulière se produit. La façon dont j'essaye de faire ceci est via des pipes nommées.Le client C# nommé Pipe ne peut pas se connecter au serveur C++

J'ai configuré un serveur de canal nommé sur l'application C++, qui semble fonctionner (le canal nommé est créé - il apparaît dans la liste récupérée par PipeList) et un client de canal nommé sur l'application C#, où il échoue: la première ligne du code client C# donne "Le handle de tuyau n'a pas été défini. Votre implémentation de PipeStream a-t-elle appelé InitializeHandle?" erreur, et la ligne 2 renvoie l'exception "Accès au chemin refusé".

Où est-ce que je me trompe?

C++ code serveur

CString namedPipeName = "\\\\.\\pipe\\TitleChangePipe"; 

HANDLE pipe = CreateNamedPipe(namedPipeName, PIPE_ACCESS_INBOUND , PIPE_WAIT, 1, 1024, 1024, 120 * 1000, NULL); 
if (pipe == INVALID_HANDLE_VALUE) { 
    MessageBox(NULL, "Pipe Could Not be Established.", "Error: TCM", MB_ICONERROR); 
    return -1; 
} 

char line[512]; DWORD numRead; 

while (true)//just keep doing this 
{ 
    numRead = 1; 
    while ((numRead < 10 || numRead > 511) && numRead > 0) 
    { 
     if (!ReadFile(pipe, line, 512, &numRead, NULL) || numRead < 1) {//Blocking call 
      CloseHandle(pipe);           //If something went wrong, reset pipe 
      pipe = CreateNamedPipe(namedPipeName, PIPE_ACCESS_INBOUND , PIPE_WAIT, 1, 1024, 1024, 120 * 1000, NULL); 
      ConnectNamedPipe(pipe, NULL); 
      if (pipe == INVALID_HANDLE_VALUE) { 
       MessageBox(NULL, "Pipe Could Not be Established.", "Error: TCM", MB_ICONERROR); 
       return -1; } 
      numRead = 1; 
     } 
    } 
    line[numRead] = '\0'; //Terminate String 
} 

CloseHandle(pipe); 

C# Code client

var client = new NamedPipeClientStream(".", "TitleChangePipe", PipeDirection.InOut); 
client.Connect(); 
var reader = new StreamReader(client); 
var writer = new StreamWriter(client); 

while (true) 
{ 
    var input = Console.ReadLine(); 
    if (String.IsNullOrEmpty(input)) 
     break; 
    writer.WriteLine(input); 
    writer.Flush(); 
    Console.WriteLine(reader.ReadLine()); 
} 

Répondre

2

La création de canaux nommés ne pas les bons paramètres.

D'abord vous voulez lire & écrire sur le tuyau, de sorte que le drapeau à utiliser est: PIPE_ACCESS_DUPLEX

Alors, là, vous envoyez des messages en mode synchrone. Utilisez ces indicateurs: PIPE_WAIT | PIPE_TYPE_MESSAGE

Enfin, vous n'autorisez qu'une seule instance de ce tube sur la machine. Évidemment vous avez besoin d'au moins 2: Un pour le serveur un pour le client. Je voudrais simplement utiliser le drapeau illimité: PIPE_UNLIMITED_INSTANCES

HANDLE pipe = CreateNamedPipe(namedPipeName, PIPE_ACCESS_DUPLEX, \ 
           PIPE_WAIT | PIPE_TYPE_MESSAGE, PIPE_UNLIMITED_INSTANCES, \ 
           1024, 1024, 120 * 1000, NULL); 

Après avoir créé un tuyau dans le serveur, vous devez attendre contre les connexions sur ce tuyau avant de l'utiliser: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365146(v=vs.85).aspx

+0

Merci pour la réponse et les explications. J'ai changé les instances de 'CreateNamedPipe', de sorte qu'il utilise les variables conseillées de la manière décrite. En ce qui concerne l'attente des connexions sur le tuyau avant de l'utiliser, si je comprends bien, c'est ce que fait ConnectNamedPipe. Cela étant dit, je ne reçois plus l'exception 'Accès au chemin refusé', mais je reçois toujours 'Pipe handle n'a pas été défini. Est-ce que votre implémentation de PipeStream a appelé InitializeHandle? sur la première ligne du code client. – Claudiu

+1

Oui, c'est ce que fait ConnectNamedPipe, utilisez-le et pas seulement dans la boucle! Vérifiez à nouveau les noms des pipes car il peut être déroutant avec les préfixes '\\ pipe'. J'ai également trouvé un fil similaire: http://stackoverflow.com/questions/10740479/two-way-c-to-c-sharp-communication-using-named-pipes. ]] – Tezirg

+0

Merci! J'aurais aussi dû l'utiliser en dehors de la boucle, après la création du tuyau comme vous l'avez mentionné. Bien travailler maintenant :) – Claudiu