2010-03-04 9 views
7

Sono abbastanza nuovo nella programmazione e nella programmazione della rete Esp quindi se è stupido, non bash troppo duro per favore, grazie.UDP e socket, recvfrom() ritorno -1 e risorsa temporaneamente non disponibile

Ho client e server che comunicano con diagrammi (UDP) in C. client invia 5 msgs e alla ricezione di msgs, il server invia indietro msgs. ricevere e inviare messaggi è grandioso fino a quando il client ha finito di ricevere i messaggi. dopo che il server ha inviato tutti i messaggi indietro, termina utilizzando close(). quindi recvfrom() dal client dovrebbe restituire 0, giusto?

assumendo recvfrom() dovrebbe restituire 0 su close() dal lato server, restituisce -1 invece, con errore Risorsa temporaneamente non disponibile. è questo riferimento risorsa al socket chiuso dal server? o è per qualcosa di completamente diverso come l'esaurimento del buffer o qualcosa (che non penso sia vero)?

e assumendo la mia ipotesi era sbagliata e -1 viene restituito a causa di server terminato, probabilmente dovrebbe gestire l'errore con

if(SOMEMACRO) 
    do something 

ma come faccio a sapere che cosa è SOMEMACRO? stampo l'errore ma dice che la temp delle risorse non è disponibile e la descrizione recvfrom() non parla di risorse non recuperabili ..?

btw questo è un socket non bloccante, se questo fa alcuna differenza visto che ho letto che se O_NONBLOCK è impostato e nessun msg è disponibile, imposterà errno su EAGAIN o EWOULDBLOCK. O_NONBLOCK non è impostato ma è impostato MSG_DONTWAIT. sono fondamentalmente la stessa cosa in cui O_NONBLOCK è per i descrittori di file generali e MSG_DONTWAIT è specifico per il socket ??

Il mio cervello non sta funzionando molto bene ora, se qualcuno potesse illuminarmi e chiarire di cosa sia la mia confusione, lo apprezzerei molto. Grazie!

risposta

13

UDP è un protocollo stateless, a differenza di TCP che è orientato alla connessione. Il tuo codice ricevente non saprà se il mittente ha chiuso o meno il suo socket, ma sa solo se ci sono dati in attesa di essere letti. Secondo la pagina man per recvfrom su Linux:

Se nessun messaggio sono disponibili presso la presa, il ricevere chiamate attendere un messaggio per arrivare, a meno che la presa sia bloccano il sistema (vedi fcntl (2)), nel qual caso viene restituito il valore -1 e la variabile esterna errno impostata su EAGAIN.

questo sembra essere ciò che sta accadendo per voi

Edit: Si noti che "risorsa temporaneamente non disponibile" e EAGAIN sono lo stesso errore, uno è proprio il descption user friendly vs il nome definire.Fondamentalmente sta solo dicendo che stai cercando di leggere dalla presa e non ci sono dati da leggere

+1

Quindi se stai usando UDP, recvfrom() restituirà mai 0? dal momento che non sai mai se il peer ha eseguito un arresto regolare? –

+2

@Fantastic Fourier - UDP può effettivamente inviare un datagramma che è solo l'IP e le intestazioni UDP ma nessun carico utile di dati. È perfettamente legale e ti sembrerà una lettura di 0 byte. – Duck

+0

@Fantastic Fourier - A rigor di termini visto che non esiste una "connessione" in UDP, non c'è nulla da spegnere, ordinato o meno. – Duck

2

Dopo aver chiuso la presa, rimane ancora per un po '. Di solito circa due minuti o giù di lì. Per evitare ciò, utilizzare l'opzione socket SO_REUSEADDR.

Ecco alcuni riferimenti per voi.

http://msdn.microsoft.com/en-us/library/ms740476%28VS.85%29.aspx http://docs.hp.com/en/B2355-90136/ch03s01.html

E qui è un esempio, scorrere fino a udp_listen funzione:

http://www.codase.com/search/display?file=L2dlbnRvbzIvdmFyL3RtcC9yZXBvcy9jb2Rhc2UuYy9zbGlycC0xLjAuMTYvd29yay9zbGlycC0xLjAuMTYvc3JjL3VkcC5j&lang=c&off=15730+15796+

Problemi correlati