2010-12-31 6 views
5

Ho rifatto questo post perché la mia scelta di titolo era orribile, mi dispiace per quello. Il mio nuovo post può essere trovato qui: After sending a lot, my send() call causes my program to stall completely. How is this possible?Sto usando tcp per molte piccole mandate, dovrei disattivare l'algoritmo di Nagles? (Le persone lo sanno anche come TCP_NODELAY)

Grazie mille a tutti. Il problema era che i client erano effettivamente bot e non leggevano mai dalle connessioni. (Sembra stupido)

+0

Puoi semplicemente modificare il titolo, lo sai. – caf

+0

Haha ho provato a ma non riuscivo a capirlo. Avrei preferito che: /. – returneax

risposta

4

TCP_NODELAY potrebbe aiutare la latenza di piccoli pacchetti dal mittente al ricevente, ma la descrizione ha dato punti in direzione diversa. Posso immaginare quanto segue:

  • Invio più dati di quelli riceventi consumano effettivamente - questo alla fine buffer overflow del mittente (SO_SNDBUF) e fa sì che il processo server di apparire "bloccato" nella chiamata di sistema send(2). A questo punto il kernel attende che l'altra parte riconosca alcuni dei dati in sospeso, ma il ricevitore non se lo aspetta, quindi non lo fa recv(2).

Probabilmente ci sono altre spiegazioni, ma è difficile dirlo senza vedere il codice.

+0

Ciao Nikolai, so per certo che i clienti non leggono mai i dati. I client vengono simulati da un altro programma. Se non ricevono mai dati, questo causerà un overflow del mio buffer? – returneax

+0

Sì, questo è il modo in cui funziona TCP. –

+0

Al secondo pensiero, sembra che UDP possa soddisfare meglio le tue esigenze. –

2

Nagle's non causerebbe la "scomparsa nel kernel", motivo per cui disabilitarlo non ti aiuta. Nagle memorizzerà solo i dati per un po 'di tempo, ma alla fine li invierà senza alcun tipo di richiesta da parte dell'utente.

C'è qualche altro colpevole.


Modifica per la domanda aggiornata.

È necessario assicurarsi che il client riceva tutti i dati inviati e che lo stia ricevendo rapidamente. Chiedi a ciascun cliente di scrivere su un registro o qualcosa da verificare.

Ad esempio, se un client è in attesa che il server accetti l'aggiornamento a 23 byte, potrebbe non ricevere i dati. Ciò può causare il riempimento del buffer di invio del server, il che causerebbe il degrado e l'eventuale deadlock.

Se questo è davvero il colpevole, la soluzione sarebbe una comunicazione asincrona, come la libreria Asio di Boost.

+0

Sì, questo è quello che pensavo. Comunque sono davvero indizio. Qualcosa che stavo osservando è la dimensione del buffer tcp forse ... Non lo so davvero -_- – returneax

+0

@returneax Puoi modificare la tua domanda per includere il codice che stai utilizzando per inviare/recuperare dati su entrambi i client e il server? Mi chiedo se stai facendo qualcosa per causare un deadlock, ecc. – chrisaycock

+0

Certo, il client è scritto in C# e il mio amico lo sta scrivendo, ma per ora posso darti il ​​codice del server. Anche il server è multithreaded ... – returneax

4

Se send() sta bloccando su un socket TCP, indica che il buffer di invio è pieno, che a sua volta indica che il peer all'altro capo della connessione non sta leggendo i dati abbastanza velocemente. Forse quel client è completamente bloccato e non chiama lo recv() abbastanza spesso.