2010-12-31 3 views
14

Hi
voglio usare NamedPipeServerStream che è nuovo da .NET 3.5 per la comunicazione NamedPipe. Voglio scrivere server pipe multi-thread. è gestito di default o dovrei scrivere il codice per quello. il mio server pipe dovrebbe gestire più richieste alla voltamultithread NamePipeServer in C#

qualsiasi soluzione o codice?

+0

cosa è il numero massimo di richiesta da un client a un server di nome pipe? – Ehsan

+0

Non esiste un limite al numero di letture e scritture che un client può eseguire su una named pipe per tutto il tempo in cui entrambe le estremità della pipe sono aperte. –

risposta

20

Ogni istanza NamedPipeServerStream è un'implementazione Stream che include un handle per un'istanza di una named pipe. È possibile (e un server pipe multithreading avrà) più istanze di NamedPipeServerStream per la stessa named pipe: ognuna avvolge un handle in un'istanza diversa della named pipe, servendo un client diverso. Le istanze di named pipe (anche per la stessa pipe) sono tenute separate dal sistema operativo, quindi non è necessario alcun codice esplicito per mantenere separate le comunicazioni di ciascun client con il server.

Quello che è necessario codificare esplicitamente è il modello di threading per il server. L'approccio più semplice al multithreading del server è spiegato in this SO answer, che include un modello di pseudo-codice. Implementazioni più scalabili, se è necessario supportare un numero elevato di chiamanti concorrenti, utilizza il pooling di thread e i metodi asincroni invece di creare un thread dedicato per ciascuna connessione.

+0

Quindi dobbiamo creare un nuovo flusso server per ogni cliente? – Ehsan

+1

Sì, è giusto –

0

NamedPipeServerStream è una connessione point-to-point. È necessario sincronizzare personalmente le chiamate, ad esempio le chiamate scritte in coda e il server che legge dalla coda sincronizzata e effettua le chiamate.

24

È possibile scrivere un server pipe multi thread creando ripetutamente un NamedPipeServerStream e attendendo una connessione, quindi creando un thread per quell'istanza di NamedPipeServerStream.

È possibile avere solo 254 client simultanei secondo la documentazione MSDN .NET collegata di seguito. Per le API Win32, tuttavia, è possibile passare un valore speciale per ottenere un numero illimitato in base alle risorse di sistema. Sembra che la documentazione MSDN sia errata come indicato di seguito.

Il codice qui sotto non è testato quindi per favore non semplicemente copiare e incollare per l'uso in produzione, senza prove:

public class PipeServer 
    { 
     bool running; 
     Thread runningThread; 
     EventWaitHandle terminateHandle = new EventWaitHandle(false, EventResetMode.AutoReset); 
     public string PipeName { get; set; } 

     void ServerLoop() 
     { 
      while (running) 
      { 
       ProcessNextClient(); 
      } 

      terminateHandle.Set(); 
     } 

     public void Run() 
     { 
      running = true; 
      runningThread = new Thread(ServerLoop); 
      runningThread.Start(); 
     } 

     public void Stop() 
     { 
      running = false; 
      terminateHandle.WaitOne(); 
     } 

     public virtual string ProcessRequest(string message) 
     { 
      return ""; 
     } 

     public void ProcessClientThread(object o) 
     { 
      NamedPipeServerStream pipeStream = (NamedPipeServerStream)o; 

      //TODO FOR YOU: Write code for handling pipe client here 

      pipeStream.Close(); 
      pipeStream.Dispose(); 
     } 

     public void ProcessNextClient() 
     { 
      try 
      { 
       NamedPipeServerStream pipeStream = new NamedPipeServerStream(PipeName, PipeDirection.InOut, 254); 
       pipeStream.WaitForConnection(); 

       //Spawn a new thread for each request and continue waiting 
       Thread t = new Thread(ProcessClientThread); 
       t.Start(pipeStream); 
      } 
      catch (Exception e) 
      {//If there are no more avail connections (254 is in use already) then just keep looping until one is avail 
      } 
     } 
+0

@Brian: Perché dici "puoi avere solo 254 client concorrenti"? Per impostazione predefinita, NamedPipeServerStream specifica PIPE_UNLIMITED_INSTANCES quando si chiama l'API Win32 CreateNamedPipe e la documentazione di Win32 dice "il numero di istanze di pipe che è possibile creare è limitato solo dalla disponibilità di risorse di sistema". –

+0

'ArgumentOutOfRangeException' viene generato quando' maxNumberofServerInstances è inferiore a uno o maggiore di 254. http://msdn.microsoft.com/en-us/library/bb355105.aspx –

+2

@Brian: la documentazione per il bug NamedPipeServerStream. Anche il valore '-1', corrispondente a' PIPE_UNLIMITED_INSTANCES', è un valore accettabile. 'if (((maxNumberOfServerInstances <1) || (maxNumberOfServerInstances> 0xfe)) && (maxNumberOfServerInstances! = -1)) { throw new ArgumentOutOfRangeException (" maxNumberOfServerInstances ", SR.GetString (" ArgumentOutOfRange_MaxNumServerInstances ")); } ' –