|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3739
|
[C/VB] perdita di pacchetti
ciao,
mi interessava capire quali sono le cause principali della perdita di pacchetti a livello applicativo. Il protocollo TCP/IP garantisce che tutti i pacchetti vengono inviati/ricevuti da due macchine in rete ma nel caso in cui una macchina client fatica ad elaborare i pacchetti in arrivo per ragioni a me ancora ignote, dove finiscono tali pacchetti? Faccio un esempio: ho due thread i quali inviano rispettivamente ogni 200 ms: thread A 127 x 8 bit = 1016 bit ogni bit è accompagnato da alcune informazioni utili a capire a chi appartiene tale bit, la lunghezza di ogi messaggio è quindi mediamente lunga 30 byte quindi: 1016 x 30 x 5 = 148,82 KB/s circa thread B 4000 x 8 bit = 32000 bit ogni bit è accompagnato da alcune informazioni utili a capire a chi appartiene tale bit, la lunghezza di ogi messaggio è quindi mediamente lunga 30 byte quindi: 32000 x 30 x 5 = 4687,5 KB/s circa p.s. ho editato e corretto i dati Ultima modifica di misterx : 09-09-2013 alle 11:34. |
|
|
|
|
|
#2 | ||
|
Senior Member
Iscritto dal: Sep 2005
Città: Torino
Messaggi: 606
|
Quote:
Quote:
"ogni bit è accompagnato da alcune informazioni utili" cioè altri bit?? un pò troppo overhead, non credi?
__________________
"Se proprio dovete piratare un prodotto, preferiamo che sia il nostro piuttosto che quello di qualcun altro." [Jeff Raikes] "Pirating software? Choose Microsoft!" |
||
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3739
|
ciao,
siccome sto lavorando con le socket penso di trovarmi al livello 7 dove regnano ftp e compagnia bella Mi sono accorto che con i miei conti sono stato poco chiaro; riassumendo ho nella pratica due cicli nidificati: sorta di pseudocodice Codice:
int c,d,e,f;
char msg[1024];
for(int byte=0; byte < 4000; byte++)
{
for(int bit=0; bit<8;bit++) {
sprintf(msg"%d, %d, %d, %d %d, %d",byte,bit,c,d,e,f);
SendText(msg);
}
}
Sleep(200); // attende 200 ms prima di inviare i prossimi 'n' messaggi
Quindi: 4000 x 8 = 32000 byte ogni 200 ms, quindi ogni secondo: 32000 x 5 = 156,25 KB/s Ultima modifica di misterx : 15-09-2013 alle 12:07. |
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: Sep 2005
Città: Torino
Messaggi: 606
|
ok, livello "applicazione" e usi le socket. Suppongo che tu stia usando SOCK_STREAM e non SOCK_DGRAM. Suppongo ancora che l'applicazione comunichi con un endpoint appartenente alla stessa LAN, così da escludere i problemi connessi ai router etc.
Allora puoi avere perdite di pacchetto per i seguenti motivi: - la scheda di rete non riesce a smaltire i pacchetti in entrata abbastanza velocemente. (scenario quasi impossibile) - il sistema operativo non riesce a smaltire i buffer del kernel (anche qui difficile che accada) - lo switch non riesce a smaltire il traffico, i suoi buffer sono pieni. in tutti questi casi i pacchetti vengono droppati, in tutti i casi il tcp/ip provvede al recovery. In più c'è da dire che le trame non vengono inviate dalla scheda di rete con la velocità con cui tu invii pacchetti tramite codice, il sistema operatvo intercede praticamente sempre. E poi esiste anche la "finestra" del tcp.
__________________
"Se proprio dovete piratare un prodotto, preferiamo che sia il nostro piuttosto che quello di qualcun altro." [Jeff Raikes] "Pirating software? Choose Microsoft!" |
|
|
|
|
|
#5 | |
|
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3739
|
Quote:
Ho notato però che i pacchetti ricevuti dal client, a volte sono lunghi 1460 byte, ed a volte solo 1 byte. Ogni pacchetto ricevuto dal client scatena un evento; sembra quasi che siano i troppi eventi a causare la perdita di pacchetti e quindi vengono scartati. Ho notato anche che se porto il tempo da 200 ms a 50 ms l'applicativo in VB non è più governabile; potrebbe essere anche un limite del linguaggio, anche se ho più di qualche dubbio? Considerando la relativa quantità di dati che invio al client a mio avviso dovrebbe funzionare tutto tranquillamente. |
|
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Sep 2005
Città: Torino
Messaggi: 606
|
non conosco affatto vb, ma forse è un problema di applicazione.
se scateni un evento per pacchetti di un byte è ovvio che carichi parecchio l'applicazione così da non riuscire a star dietro ai pacchetti ricevuti. Ad ogni modo, a livello di codice, se ovviamente non fai errori, non hai alcuna perdita. Puoi comunque causarla ai buffer del kernel, scheda di rete etc.
__________________
"Se proprio dovete piratare un prodotto, preferiamo che sia il nostro piuttosto che quello di qualcun altro." [Jeff Raikes] "Pirating software? Choose Microsoft!" |
|
|
|
|
|
#7 | |
|
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3739
|
Quote:
però temo che i pacchetti da 1 byte vengano deciso dal sistema operativo in quanto io a livello applicativo invio messaggi completi. |
|
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: Sep 2005
Città: Torino
Messaggi: 606
|
non so, mi pare proprio strano. Di solito capita che crei ed invii un pacchetto troppo piccolo che il SO aspetta ad inviarlo e lo unisce ad altri.
__________________
"Se proprio dovete piratare un prodotto, preferiamo che sia il nostro piuttosto che quello di qualcun altro." [Jeff Raikes] "Pirating software? Choose Microsoft!" |
|
|
|
|
|
#9 | |
|
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3739
|
Quote:
Ho del tutto tralasciato il fatto di verificare quanti dati sono stati realmente inviati attraverso la SendText(). La documentazione dice che è possibile capire quanti dati sono stati inviati ma non mi è ancora chiaro come gestire il problema. Per lo sviluppo uso Borland builder. |
|
|
|
|
|
|
#10 |
|
Senior Member
Iscritto dal: Sep 2005
Città: Torino
Messaggi: 606
|
se vuoi un consiglio spassionato, apri 2 istanze di wireshark e cattura il traffico del server e del client, così puoi vedere esattamente cosa sta succedendo.
Cos'è SendText()?l'hai scritta tu?pensavo fosse una funzione di libreria ma non la trovo in rete.
__________________
"Se proprio dovete piratare un prodotto, preferiamo che sia il nostro piuttosto che quello di qualcun altro." [Jeff Raikes] "Pirating software? Choose Microsoft!" |
|
|
|
|
|
#11 | |
|
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3739
|
Quote:
Ho provato come suggerito dalla lettura della documentazione una cosa del tipo: Codice:
int test;
test = SendText(buffer); // lunghezza dei dati inviati
if(test < strlen(buffer)) VisualizzaMessaggio("Problema");
Ultima modifica di misterx : 09-09-2013 alle 15:36. |
|
|
|
|
|
|
#12 | |
|
Senior Member
Iscritto dal: Sep 2005
Città: Torino
Messaggi: 606
|
Quote:
Per il resto non so autarti, non conosco VB, aspettiamo che passa qualcuno ferrato.
__________________
"Se proprio dovete piratare un prodotto, preferiamo che sia il nostro piuttosto che quello di qualcun altro." [Jeff Raikes] "Pirating software? Choose Microsoft!" |
|
|
|
|
|
|
#13 | |
|
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3739
|
Quote:
Quello che dici lo avevo notato, avevo provato a contare ogni send lato server ed ogni gettext lato client ed ho notato che non esiste un rapporto 1:1. Ora stavo leggendo anche che la SendText() ritorna il numero di caratteri che è riuscita a scrivere sulla socket, per questo motivo avevo effettuato il test sopra. Mi è parso anche di capire che sto usando una socket bloccante. Comunque domani provo a sniffare quanto arriva sulla scheda del client; grazie ancora. Se non ricordo male wireshark esiste anche in versione portable. |
|
|
|
|
|
|
#14 |
|
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3739
|
rettifico, avendo poca destrezza con l'uso dei componenti di bcb ho scoperto che stavo usando il componente TServerSocket in modalità NON bloccante ed in questo modo usando Putty ad esempio, perdevo dati.
Dopo aver settato la socket bloccante i dati arrivano tutti. Anche dopo aver letto diversi articoli in rete non mi è del tutto chiara la differenza tra socket bloccante e non. |
|
|
|
|
|
#15 | |
|
Senior Member
Iscritto dal: Sep 2005
Città: Torino
Messaggi: 606
|
Quote:
Quando è bloccante (in genere è il comportamento di default) tale chiamata a funzione sospende l'esecuzione del programma finchè non sono stati ricevuti dati (quanti dipende dal SO) in ingresso sulla socket. Non bloccante vuol dire che la funzione ritorna immediatamente, sia nel caso in cui sono stati letti dei dati sia che non sia arrivato niente. Anzi, in generale, i dati devono ancora arrivare quando la funzione ritorna. Questa modalità viene utilizzata in applicazioni parallele dove il controllo è critico. Usa la socket bloccante
__________________
"Se proprio dovete piratare un prodotto, preferiamo che sia il nostro piuttosto che quello di qualcun altro." [Jeff Raikes] "Pirating software? Choose Microsoft!" |
|
|
|
|
|
|
#16 | |
|
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3739
|
Quote:
Settando la proprietà bloccante le cose sembrano essersi sistemate ma rimane per me ancora un mistero. Essendo il server implementato attraverso un thread mi è chiaro che a livello di interfaccia non mi accorgo che il codice in esso viene bloccato sino alla ultimazione della SendText(). Ho letto ogni tipo di manuale di BCB ed ancora non ne sono venuto a capo, mi piacerebbe riuscire a trattare anche la socket non bloccante. ciao |
|
|
|
|
|
|
#17 |
|
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3739
|
oggi ho sperimentato la limitazione delle socket bloccanti; se due client si collegano al server ed uno dei due si blocca per una qualche ragione, anche all'altro client non arrivano più dati
|
|
|
|
|
|
#18 |
|
Senior Member
Iscritto dal: Sep 2005
Città: Torino
Messaggi: 606
|
Se si blocca il server! scusa ma stai usando un server multithread, giusto?
__________________
"Se proprio dovete piratare un prodotto, preferiamo che sia il nostro piuttosto che quello di qualcun altro." [Jeff Raikes] "Pirating software? Choose Microsoft!" |
|
|
|
|
|
#19 |
|
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3739
|
|
|
|
|
|
|
#20 | |
|
Senior Member
Iscritto dal: Sep 2005
Città: Torino
Messaggi: 606
|
Quote:
se il server usa un solo thread (quello principale del processo) si bloccherà sulla accept() in attesa di un client. Quando un client si connette, il server "ritorna" dalla accept e comincia la comunicazione. Anche utilizzando la solita struttura con il ciclo infinito: Codice:
int client = -1;
while (client = accept(server, (struct sockaddr *) &address, &address_len)) != -1)
{
... tuo protocollo
}
In sintesi 2 o più client senza server multithread non possono essere serviti contemporaneamente.
__________________
"Se proprio dovete piratare un prodotto, preferiamo che sia il nostro piuttosto che quello di qualcun altro." [Jeff Raikes] "Pirating software? Choose Microsoft!" |
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 20:19.




















