2011-10-28 14 views
13

La maggior parte dei datagrammi che ricevono funzioni come recV o read di c, classe DatagramPacket javas o SocketServer pythons, includono la possibilità di scoprire la quantità di dati ricevuti.I datagrammi sono sempre ricevuti completamente?

c:

int amount = recv(sock, buf, n, MSG_WAITALL); 

java:

int amount = datagramSocket.getLength(); 

pitone:

class MyUDPHandler(socketserver.BaseRequestHandler): 
    def handle(self): 
     amount = len (self.request[0]) 

Sono questi affidabile? Oppure è possibile che vengano ricevute solo parti del messaggio, a causa ad esempio della frammentazione dei pacchetti o del ritardo della rete?
In altre parole: quando invio un blocco di dati di lunghezza variabile via udp e lo ricevo dall'altra parte, questi valori sono esattamente uguali alla dimensione del blocco originale?

Modifica:
ninjalj ha fatto un buon punto e voglio includerlo qui. Cosa succede quando la funzione di ricezione viene interrotta, ad esempio da un segnale? Cosa succede quando due thread cercano contemporaneamente di ricevere dallo stesso socket?

+0

just fyi, il tuo codice java ha una grave mancanza di ortografia di "Lunghezza" – Necrolis

risposta

13

I datagrammi UDP non possono essere forniti parzialmente¹; sono consegnati così come sono o non lo sono affatto. Quindi sì, puoi essere sicuro che il datagramma ricevuto è stato inviato esattamente come lo vedi alla fine del destinatario.

Modifica per incorporare il commento di Will, che è il miglior tipo di corretta (vale a dire, tecnicamente):

¹They può essere frammentato a livello IP, ma lo stack di rete sul lato ricevitore sia completamente ricomporre un datagramma e passarlo al processo di ascolto come inviato, o non riconoscerà che tutti i dati sono stati ricevuti.

+8

I pacchetti tecnicamente grandi possono essere frammentati, ma il protocollo gestisce la frammentazione e il riassemblaggio e se non può essere riassemblato completamente è contrassegnato come perso, quindi l'utente non lo noterò mai. – Will

+1

Will è corretto. Lo stack UDP nel sistema operativo si occupa della frammentazione, ma la frammentazione è un'attività a livello IP. Quindi si applica a TCP e UDP allo stesso modo. Detto questo, i pacchetti UDP non sono garantiti per la consegna. Quindi qualsiasi ritrasmissione deve essere gestita dal tuo programma. – nemith

+2

Tuttavia, se il proprio buffer su recv() non è abbastanza grande da contenere il pacchetto, si otterranno dati troncati. – nos

4

I datagrammi parziali sono consentiti solo con UDP Lite.

Problemi correlati