2012-08-01 11 views
10

UPDATE: Guardando attraverso il protocollo here, non riesco a capire cosa va inserito nel Record Envelope Unsized. Non riesco a trovare alcun esempio online.Come si chiama un metodo WCF da C++ usando pipe Named?

ORIGINALE:

Ho il seguente servizio WCF

static void Main(string[] args) 
    { 
     var inst = new PlusFiver(); 
     using (ServiceHost host = new ServiceHost(inst, 
      new Uri[] { new Uri("net.pipe://localhost") })) 
     { 
      host.AddServiceEndpoint(typeof(IPlusFive), new NetNamedPipeBinding(NetNamedPipeSecurityMode.None), "PipePlusFive"); 
      host.Open(); 
      Console.WriteLine("Service is Available. Press enter to exit."); 
      Console.ReadLine(); 
      host.Close(); 
     } 
    } 

    [ServiceContract] 
    public interface IPlusFive 
    { 
     [OperationContract] 
     int PlusFive(int value); 
    } 


    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] 
    public class PlusFiver : IPlusFive 
    { 
     public int PlusFive(int value) 
     { 
      Console.WriteLine("Adding 5 to " + value); 
      return value + 5; 
     }  
    } 

ho uscita aggiungendo 5 linea quindi so se il server ha elaborato la richiesta o meno.

Ho un client .NET che ho usato per testarlo e tutto funziona come previsto.

Ora voglio creare un client C++ non gestito per questo.

Ho capito come ottenere il nome della pipa e scriverlo.
Ho scaricato il protocollo da here

Posso scrivere sul pipe ma non riesco a leggerlo. Ogni volta che provo a leggere da esso ottengo un errore ERROR_BROKEN_PIPE 109 (0x6D) The pipe has been ended.. Se sostituisco la lettura con una scrittura, la scrittura ha successo, quindi non penso che la pipe sia chiusa, almeno non finché non provo a leggere.

Ecco come mi collego al tubo.

HANDLE OpenPipe(OLECHAR* bstrGuid) 
{ 
    wstring pipeName = L"\\\\.\\pipe\\"; 
    wstring strGuid = bstrGuid; 
    pipeName.append(strGuid.substr(1,36)); 
    wcout << "Pipe Name " << endl; 
    wcout << pipeName.c_str() << endl; 

    HANDLE hPipe = CreateFile(pipeName.c_str(), GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL); 
    if(hPipe == INVALID_HANDLE_VALUE) 
    { 
     wcout << "failed to create pipe" << endl; 
     system("pause"); 
     return NULL; 
    } 
    return hPipe; 
} 

questo è come sto creando il primo messaggio che sto mandando

std::list<wchar_t> GetFirstMessage() 
{ 
    std::list<wchar_t> message; 
    message.push_back(0x00);// version record 
    message.push_back(0x01);// major version 
    message.push_back(0x00);// minor version 
    message.push_back(0x01);// mode record 
    message.push_back(0x01);// singleton-unsized mode 
    message.push_back(0x02);// via record 

    wstring url = L"net.pipe://localhost/PipePlusFive"; 
    message.push_back(url.length());// via length 
    for(int x= 0;x<url.length();x++) 
    { 
     message.push_back(url[x]); // via 
    } 
    message.push_back(0x03); 
    message.push_back(0x08); 
    return message; 
} 

Ecco come sto scrivendo al file.

int WriteMessage(HANDLE hPipe, LPVOID message, int size) 
{ 
    DWORD bytesWritten; 

    BOOL bWrite = WriteFile(hPipe, &message, size, &bytesWritten, NULL); 
    wcout << "Bytes Written: " << bytesWritten << endl; 
    if(bWrite == false) 
    { 
     wcout << "fail"<<endl; 
     CloseHandle(hPipe); 
     system("pause"); 
     return 1; 
    } 
    return 0; 
} 

    list<wchar_t> full_message = GetFirstMessage(); 
int result = WriteMessage(hPipe, &full_message, full_message.size()); 
if (result == 1) 
{ return 1;} 

Ecco come sto scrivendo il messaggio di fine

wchar_t message = 12; 
result = WriteMessage(hPipe, &message, 1); 
if (result == 1) 
{ return 1;} 

Ecco come sto cercando di leggere la risposta

char buffer[10]; 
DWORD bytesRead; 
BOOL bRead = ReadFile(hPipe, buffer, 1, &bytesRead, NULL); 
if(bRead == false) 
{ 
    wcout << "fail read"<<endl; 
    wcout << "error: " << GetLastError() << endl; 
    CloseHandle(hPipe); 
    system("pause"); 
    return 1; 
} 

Sono nuovo di C++, così Non so se non sto seguendo il protocollo correttamente o commettendo uno stupido errore nel modo in cui sto provando a farlo?

UPDATE: Il problema era che stavo scrivendo l'indirizzo del puntatore alla named pipe invece del contenuto della lista. L'ho risolto e ora sono in grado di leggere il Preamble Ack Record. Ora devo capire che cosa deve essere inviato per la parte successiva del protocollo.

+0

Non è possibile utilizzare il C++ gestito o un altro legame WCF più semplice (REST, ecc.)? –

+0

Non riesco a utilizzare il C++ gestito. Penso che il RESTO dovrebbe rallentare. – scott

+0

Ecco una soluzione qui: http://stackoverflow.com/questions/686452/create-wcf-service-for-unmanaged-c-clients ma utilizza alcuni pezzi di C++ gestito –

risposta

0

Controllare se questo funziona per voi

  1. tenta di aprire una named pipe. (CreateFile)
  2. Impostare la modalità di lettura e la modalità di blocco della named pipe specificata. (SetNamedPipeHandleState)
  3. Invia un messaggio al server pipe e riceve la sua risposta. (WriteFile, ReadFile)
  4. Chiudere il tubo.(CloseHandle)
Problemi correlati