2011-02-17 12 views
10

La mia app server utilizza un TIdTCPServer, diverse app client utilizzano TIdTCPClients per connettersi al server (tutti i computer si trovano nella stessa LAN).Best practice: mantenere la connessione TCP/IP aperta o chiusa dopo ogni trasferimento?

Alcuni client devono contattare il server solo ogni due minuti, altri una volta al secondo e uno lo fa circa 20 volte al secondo.

Se tengo aperta la connessione tra un client e il server, salverò la riconnettersi, ma devo controllare se la connessione è andata persa.

Se chiudo la connessione dopo ogni trasferimento, deve riconnettersi ogni volta, ma non è necessario verificare se la connessione è ancora presente.

Qual è il modo migliore per farlo?

A quale frequenza di trasferimenti di dati devo mantenere la connessione aperta in generale?

Quali sono altri vantaggi/svantaggi per entrambi gli scenari?

+3

Il sovraccarico di creazione di una nuova connessione TCP è principalmente di alcuni roundtrip. E quelli sono abbastanza veloci su LAN. Quindi chiuderei la connessione dopo alcuni secondi di non utilizzo. – CodesInChaos

+3

Ma lo scriverei in modo semplicissimo (molto probabilmente la chiusura istantanea) e poi controllerò se le prestazioni sono soddisfacenti. – CodesInChaos

+4

Vedere la mia risposta a questa domanda: http://stackoverflow.com/questions/4872800/socket-open-and-close-on-1-sec-or-to-hold-open/4873002#4873002 –

risposta

8

Vorrei suggerire un mix dei due. Quando viene aperta una nuova connessione, avviare un timer di inattività per esso. Ogni volta che vengono scambiati dati, ripristinare il timer. Se il timer scade, chiudere la connessione. Se la connessione è stata chiusa quando è necessario inviare i dati, aprire una nuova connessione e ripetere. In questo modo, le connessioni meno frequenti possono essere chiuse periodicamente, mentre le connessioni più spesso utilizzate possono rimanere aperte.

+0

Remy, bel lavoro su Indy negli ultimi anni ;-) Uso estesamente le componenti TCP di Indy, e intendo estesamente, come parte intrinseca del mio framework applicativo distribuito. Potresti dare un'occhiata a questo. – Misha

6

Mentre può essere opportuno connettersi e disconnettersi per un'applicazione attiva una volta ogni pochi minuti, l'applicazione che comunica più volte al secondo vedrà un aumento delle prestazioni lasciando aperta la connessione.

Inoltre, il codice sarà molto semplice se non si sta tentando di aprire, chiudere o diagnosticare costantemente una connessione aperta. Con la corretta logica di apertura e chiusura e SEH attorno alle tue letture e scritture, non c'è motivo di testare se il socket è ancora connesso prima dell'uso, basta usarlo. Ti dirà quando c'è un problema.

Mi piacerebbe mantenere aperta una singola connessione nella maggior parte delle applicazioni aziendali. Generalmente porterà a un codice più pulito, che è più facile da mantenere.

/twocents

8

due centesimi da esperimento ...

Il mio primo TCP/un'applicazione client/server IP è stato utilizzato un nuovo collegamento e un nuovo thread per ogni richiesta ... anni fa ...

Quindi ho scoperto (utilizzando ProcessExplorer) che ha consumato alcune risorse di rete perché tutte le connessioni chiuse non sono effettivamente distrutte, ma rimangono in uno stato particolare per qualche tempo. Sono stati creati molti thread ...

Ho avuto anche qualche problema di connessione con molte richieste concurose: non avevo abbastanza porte sul mio server!

Quindi I rewrote it, seguendo lo schema HTTP/1.1 e la funzione KeepAlive. È molto più efficiente, usa un piccolo numero di thread e ProcessExplorer adora il mio nuovo server. E non esco mai più dal porto. :)

Se il cliente deve essere arresto, userò un ThreadPool per, almeno, non creare un thread per client ...

In breve: se è possibile, mantenere il vostro cliente connessioni attive per alcuni minuti.

3

Immagino che tutto dipenda dal tuo obiettivo e dalla quantità di richieste fatte sul server in un dato momento per non menzionare la larghezza di banda disponibile e l'hardware sul server.

Hai bisogno di pensare anche per il futuro, c'è qualche possibilità che in futuro ti servano connessioni da lasciare aperte? se è così, allora hai risposto alla tua stessa domanda.

Ho implementato un sistema di chat per un progetto in cui ~ 50 persone (il numero è in crescita ogni 2 mesi) sono sempre connesse e inoltre la chat include anche il trasferimento dei dati, la manipolazione del database utilizzando determinati comandi, ecc. l'implementazione è mantenere la connessione al server aperta dall'avvio dell'applicazione fino alla chiusura dell'applicazione, nessun problema fino ad ora, tuttavia se una connessione viene persa per qualche motivo viene automaticamente ristabilita e tutto prosegue senza problemi.

Nel complesso suggerisco di provare entrambi (mantenere la connessione aperta e chiuderla dopo l'uso) e vedere quale si adatta meglio alle proprie esigenze.

3

A meno che non si riduca a molte centinaia di connessioni simultanee, lo terrei sicuramente aperto: questa è di gran lunga la migliore delle due opzioni. Una volta ridimensionate le centinaia di migliaia di connessioni simultanee, potrebbe essere necessario disconnettersi e riconnettersi. Ho architettato il mio intero framework attorno a questo (http://www.csinnovations.com/framework_overview.htm) poiché mi consente di "spingere" i dati sul client dal server ogni volta che è necessario. Devi scrivere un bel po 'di codice per assicurarti che la connessione sia attiva e funzionante (interruzioni di rete, ping temporizzati, ecc.), Ma se lo fai nel tuo "framework" allora il tuo codice applicativo può essere scritto in tale modo che tu possa presumere che la connessione sia sempre "su".

0

Il problema è il limite di thread per applicazione, circa 1400 thread. Quindi max 1300 client collegati contemporaneamente + -.

+0

Anche se il pool di thread del sistema operativo preferirei vedere implementato nei server Indy (piuttosto che per thread client), ciò che rivendichi qui non è corretto - vedi ad es. https://blogs.msdn.microsoft.com/oldnewthing/20050729-14/?p=34773 – Victoria

0

Quando si chiudono le connessioni come client, la porta utilizzata non sarà disponibile per un po 'di tempo. Quindi ad alto volume stai usando un sacco di porte diverse. Per qualsiasi cosa ripetitiva la terrei aperta.