2012-04-24 8 views
5

Ho bisogno di connettermi a migliaia di client su TCP su un protocollo proprietario per acquisire ciclicamente i dati. Ho bisogno di scrivere un'applicazione server .NET in C#.Polling su migliaia di socket TCP

Il primo tentativo è stato quello di creare per ogni socket TCP un proprio thread, che funziona ma richiede un sacco di utilizzo della CPU.

Ho scoperto che sarebbe stata un'idea migliore utilizzare il threadpool .NET. Per quanto ho capito (http://msdn.microsoft.com/en-us/library/ms973903.aspx) potrei usare i timer per far sì che ogni socket acquisisca i dati ciclicamente in un dato periodo (come 1 secondo). Questo non funziona per me perché i socket scadono una volta che la connessione è stata aperta, perché ci sono molti altri socket che devono essere aperti prima che i socket aperti girino di nuovo.

Un'altra prova era l'uso di callback asincroni. Questo funzionerebbe per me ma non so come far acquisire ciclicamente i dati ???

+2

Le parole "migliaia" e "discussioni" non vanno di pari passo. Prova a vedere se puoi usare la parola chiave 'await' per le continuazioni, questo ti permetterà di scrivere codice contro il blocco delle porte senza che il codice blocchi realmente molto spesso. Questa è una sorta di principio dietro a Erlang e Stackless Python: due linguaggi creati appositamente per la concorrenza in rete. –

+1

Perché è necessario scorrere i client per acquisire i dati? sarebbe più semplice (anche se è relativo) tenere semplicemente una lettura asincrona postata su ogni socket ed elaborare i dati man mano che arrivano. Se hai davvero bisogno di letture cicliche, potresti posticipare il repost di una lettura asincrona fino a quando tutti gli altri socket non saranno stati pubblicati. –

+1

non fare sondaggi. –

risposta

6

Provare a utilizzare Socket high performance API che consente di ricevere contemporaneamente dati su un numero molto elevato di socket, senza utilizzare un thread per socket. In fondo all'articolo c'è un link per un campione completo. C'è anche un esempio nell'articolo MSDN per lo SocketAsyncEventArgs class.

+0

L'API ad alte prestazioni di Socket sembra essere in grado di gestire molte connessioni in entrata. Ho bisogno di aprire queste connessioni, invece. È possibile utilizzare anche l'API ad alte prestazioni di Socket per questo scopo? – sqeez3r

+1

Sì, creare e aprire un socket per client, quindi utilizzare ['Socket.ReceiveAsync()'] (http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.receiveasync.aspx). –

+1

L'ho implementato in questo modo e funziona benissimo. Grazie! – sqeez3r

0

Perché non inserire una coda con gli indirizzi necessari per il polling e fare in modo che il pool di thread rimuova gli elementi dalla coda da elaborare?

Una volta terminato con un elemento, inserirlo sul retro della coda.

+3

Per prima cosa, se hai molte connessioni inattive, ti perderai un sacco di tempo a controllarle senza motivo. –

+0

Penso che ciò richiederebbe troppo tempo per migliaia di connessioni. Ho bisogno di aggiornamenti da tutte le prese ogni secondo, se possibile. – sqeez3r