2009-11-15 15 views
6

Ho cercato già risposte, ma non riesco a trovare nulla di simile ...Il modo migliore per implementare il listener di socket in C#

Sono abbastanza nuovo di C#. Ho bisogno di creare un programma in C# usando WinForms. Fondamentalmente ha 2 componenti: UI e quindi ho bisogno di avere un processo che ascolti permanentemente su una porta TCP del socket. Se c'è qualcosa ricevuto, allora ho bisogno di generare un evento o qualcosa di simile in modo da poter aggiornare l'interfaccia utente.

Domanda: qual è il modo migliore per implementare un processo che deve essere ascoltato tutto il tempo mentre il programma è in esecuzione?

E poi, quando ricevo un messaggio, come posso notificare all'interfaccia utente che deve essere aggiornato?

Grazie!

risposta

1

È possibile utilizzare la classe TcpListener. C'è un esempio nella documentazione.

+0

Credo che stiano cercando più una risposta architettonica ... sembra che non siano sicuri di come integrare un TcpListener con un programma basato su eventi. – Polaris878

1

All'avvio è possibile generare (creare) una nuova discussione che ascolta i nuovi messaggi in un ciclo infinito. Una volta ricevuto un messaggio, il thread può aggiornare alcune risorse condivise (impostare un flag). Ovviamente potresti renderlo più sofisticato se hai usato una coda sincronizzata per trasferire i messaggi. O tramite WCF (anche se questo sembra eccessivo per i tuoi scopi).

1

Questo potrebbe non essere il modo migliore per farlo, ma dovrebbe funzionare ...

Si potrebbe lanciare il codice TCP ascoltatore in un nuovo thread all'avvio del programma ... In questo modo si ha la TCP ascolto del codice mentre l'interfaccia utente è disattivata. Quando qualcosa accade nel thread TCP, dovrà segnalare il thread dell'interfaccia utente da una sorta di evento o coda di eventi.

Ora, in termini di aggiornamento di un oggetto WinForms quando qualcosa viene ricevuto, credo che solo il thread che ha creato il controllo WinForms possa aggiornare i controlli. Quindi, dovrai tenerne conto anche.

Questo è un problema con cui ho già lavorato prima ... Nel mio progetto corrente faccio ciò che ho menzionato sopra ... tuttavia c'è un bel po 'di sincronizzazione dei thread per farlo funzionare.

+2

È piuttosto semplice aggiornare l'interfaccia utente da un altro thread: è sufficiente utilizzare il metodo Control.Invoke passandolo a un delegato che aggiorna l'interfaccia utente –

8

È possibile utilizzare un TcpListener che attende connessioni in entrata su un altro thread. Ogni volta che ricevi una nuova connessione, crea una nuova discussione per elaborarla. Utilizzare Control.Invoke per aggiornare l'interfaccia utente dal thread non UI. Ecco un breve esempio:

public MainForm() 
{ 
    InitializeComponents(); 
    StartListener(); 
} 

private TcpListener _listener; 
private Thread _listenerThread; 

private void StartListener() 
{ 
    _listenerThread = new Thread(RunListener); 
    _listenerThread.Start(); 
} 

private void RunListener() 
{ 
    _listener = new TcpListener(IPAddress.Any, 8080); 
    _listener.Start(); 
    while(true) 
    { 
     TcpClient client = _listener.AcceptTcpClient(); 
     this.Invoke(
      new Action(
       () => 
       { 
        textBoxLog.Text += string.Format("\nNew connection from {0}", client.Client.RemoteEndPoint); 
       } 
      ));; 
     ThreadPool.QueueUserWorkItem(ProcessClient, client); 
    } 
} 

private void ProcessClient(object state) 
{ 
    TcpClient client = state as TcpClient; 
    // Do something with client 
    // ... 
} 
+0

Perché è stato downvoted? Per favore, commenta ! Sono aperto alle critiche, ma se non so cosa c'è di sbagliato nella mia risposta, non è molto costruttivo ... –

+0

Sono solo i cosmetici, ma penso che tu abbia un punto e virgola troppo dopo questo.Invoke (...) ;; (Giusto per chiarire, non è questo il motivo per cui sei stato downvoted, almeno non da me) – Manu

Problemi correlati