Newsgroup: it.comp.os.linux.development
Titolo: select()

potreste farmi un esempio pratico di come la funzione select possa essere
usate per sapere se ci sono dati da spedire in modo che la funzioni send
non blocchi ?

 wrote:

linguaggio C ..


        struct timeval tv;
        fd_set writeset;
        tv.tv_sec = 1;
        tv.tv_usec = 0;
 
        FD_SET(sockfd, &writeset);        
        select(sockfd+1, NULL, &writeset, NULL, &tv);  
ma non so se sia quello che cerchi
ciao

 non blocchi ?
La select  non funziona proprio  cosi`... puoi  usarla per vedere  se un
eventuale chiamata a write bloccherebbe il processo perche` il fd non e`
pronto per la scrittura.
La send puo` essere o meno bloccante  non solo in base allo stato del fd
ma anche al  protocollo usato ed alla quantita` di  dati da spedire. Se,
ad esempio, usi il protocollo TCP send non ritorna fino a quando tutti i
dati sono stati impacchettati, frammentati (se necessario) e spediti. La
select  potrebbe dirti  se e`  possibile inviare  subito i  dati (e  non
attendere, ad esempio, lo svuotamento del buffer), ma non puo` prevenire
l'attesa.
Tornando alla tua domanda:
struct timeval tv;
int socket;
fd_set write_set;
socket = ....
FD_ZERO(&rfds);
FD_SET(socket, &rfds);
tv.tv_sec = 5;
tv.tv_usec = 0;
if (select(socket + 1, NULL, &write_set, NULL, &tv) {
	/* Puoi inviare */
}
In questo esempio la select aspetta per 5 secondi prima di ritornare con
-1 se  il socket  continua a  non essere pronto. Se  la inserisci  in un
ciclo devi risettare ogni volta la  struttura tv. Se non vuoi il timeout
passa NULL come ultimo parametro.
ciao
Kronos
-- 
Home: 
http://kronoz.cjb.net
"Fare l'amore con dieci donne e` fantastico, soprattutto perche` ti
 presentano un sacco di amiche." -- Fabio Di Iorio

 wrote:
perfetto !
e c'è un modo per conoscere la condizione del fd ?
cioè, c'è un modo per sapere se la connessione che io tengo aperta è
invece stata chiusa dall'altra parte ?
perchè io avevo provato con "select(socket + 1, NULL, &write_set, NULL, &tv)
" ma pure quando di là avevo chiuso la connessione, la select mi
riportava come valore 1. (+ o - ora ho capito il perchè).


se fai una recv, e questa ritorna 0, dall'altra parte la connessione è caduta
ciao

 ciao
e se non devo ricevere nessun dato ?
se la connessione c'č, recv blocca.
non cč un altro modo ?

 non cč un altro modo ?
Solo se usi il socket in modo bloccante. Puoi renderlo non bloccante
mediante un fnctl(fd, F_SETFL, O_NONBLOCK) credo (adesso non ricordo la
sintassi esatta).
--
Alessandro Staltari
staltari(a)
geocities.com

 invece stata chiusa dall'altra parte ?
In  questo  caso  effettuando  la write  la  tua  applicazione  dovrebbe
ricevere  il  signale  SIGPIPE. Potresti  usare signal  per  ignorare  i
SIGPIPE e controllare il  valore di ritorno di write: se  e` -1 ed errno
e` uguale  a EPIPE allora  il socket  e` stato chiuso. Puoi  chiudere il
socket locale e rimuoverlo dal set.
ciao
Kronos
-- 
Home: 
http://kronoz.cjb.net
Se alla sera, dopo una strepitosa vittoria, guardandoti allo
specchio dovessi notare un secondo paio di palle, che il tuo 
cuore non si riempia d'orgoglio, perche` vuol dire che ti 
stanno inculando -- Saggio Cinese

 non ce` un altro modo ?
Non facciamo casino. Stavamo parlando della send. Devi controllare il
valore di ritorno di quella.
ciao
Kronos
-- 
Home: 
http://kronoz.cjb.net
"Chi parla in tono cortese,
 ma continua a prepararsi,
 potra` andare avanti;
 chi parla in tono bellicoso
 e avanza rapidamente
 dovra` ritirarsi" Sun Tzu -- L'arte della guerra