Newsgroup: it.comp.lang.c++
Titolo: S.O.S. socket

Salve a tutti! :-)
Sto scrivendo una libreria in C++ per utilizzare i socket, vorrei sapere
come posso sbloccare una recv() in Windows!
Cerco di spiegarmi meglio:
la funzione recv e' bloccante, io vorrei inserire un timeout (come
parametro) che mi sblocchi questa funzione.
In UNIX ho utilizzato la funzione alarm che mi genera una SIG_ALARM e mi
sblocca la read uscendo per timeout! :-o
Come posso fare un timeout di questo tipo utilizzando C++ standard (in
Windows)?
Scusate se la mia domanda e' una banalita', ma sono alle prime armi! :-(
Grazie, Marco'76.

 Windows)?
Temo che Windows in questo caso non sia molto standard.
Che io sappia, ti tocca usare le API di windows, i winsock, e rinunciare,
almeno in parte, alla portabilità.
--
Alessandro Monti

 come posso sbloccare una recv() in Windows!
Facendola in un thread separato (un bel casino) oppure
usando al suo posto chiamate WSA<qualcosa> tipiche
di WinSock (non portabili a Unix).
Alex

 almeno in parte, alla portabilità.
E` probabilmente l'approccio piu` semplice.  I thread,
tuttavia, offrono un'alternativa.
Chi alla portabilita` ci tenesse davvero (anche fra vari
Unix diversi) avrebbe cautelato il proprio uso di recv
con un'opportuna select, pero`...
Alex

 ragione, ma e` uno strano uso della lingua italiana:-).
Perchè bisogna fare polemiche? Non mi pare di aver detto niente di male, nè
ho citato alcuna versione di Unix, che, se ci tieni a saperlo, non uso. Per
quanto riguarda la lingua italiana, mi pare di aver usato una forma
dubitativa ("temo che..."), per cui non ho affermato niente con certezza. Se
ci tieni, posso riformulare la frase in altro modo: "In base alla mia poca
esperienza di programmazione di socket sotto Windows, mi pare che sia
difficile realizzare codice di una certa complessità che possa essere
considerato standard, a partire dalla necessaria chiamata a WSAStartup().
Che poi ci sia un modo, delle librerie, o qualsiasi stratagemma che io non
conosco, ma che permetta di scrivere codice perfettamente portabile su
macchine UNIX, o almeno su alcune di esse, io non ne sono a conoscenza. Di
sicuro, se si usa il VC++ e si tiene conto delle indicazioni che fornisce
tale compilatore tramite il suo estesissimo Help in linea, si finisce ad
usare delle funzioni che sono tipiche di tale ambiente e pertanto poco
portabili."
Avevo fretta, per cui ho abbreviato un po'. Se uno vuole, può sempre fare le
cose in maniera "standard", a patto di usare i giusti compilatori, le giuste
librerie, o di riscriversi le funzioni di libreria, ma spesso la fatica è
maggiore del guadagno, per cui, nel contesto in cui ci troviamo, cioè IMHO
"dare una risposta veloce a chi è in difficoltà nella stesura del suo
programma", mi sembrava corretto dare un'indicazione sulla difficoltà a
rimanere allineati ad uno standard "de facto", quale può essere il Posix, in
ambiente Windows.
Spesso sacrificare in parte la portabilità può portare a tempi molto ridotti
di sviluppo, per cui io mi sento di consigliarlo nei casi che ritengo
opportuni, e la libreria winsock mi sembra proprio uno dei casi più
significativi. Se invece si vuole scrivere codice "portabile al 100%",
allora si deve anche essere disposti a pagarne il prezzo, sia in semplicità
del codice, sia in tempi di sviluppo, sia anche in prestazioni. Considerato
che comunque un programma Windows ha almeno tutta l'interfaccia utente ben
poco portabile (sempre a meno di usare strumenti particolari), togliere la
portabilità anche alla parte di gestione dei socket non mi sembra una grave
perdita.
Vorrei anche sottolineare che *normalmente* la parte che "deve" essere
portabile è solo quella relativa alla parte "businness" del programma, non
il modo in cui si interfaccia al SO, in quanto si può supporre che per
queste cose vi siano librerie specializzate che possono essere isolate dal
resto del codice. Ovviamente dipende molto dal tipo di programma che si sta
realizzando, da quanta parte del programma sia dedicata a cose diverse
rispetto all'usare le funzioni del SO, ecc.
--
Alessandro Monti

 perdita.
Un programma di server (chi altro DEVE gestire le socket in modo cosi`
robusto da non bloccarsi anche in caso di errori interni della rete?  Perche`
solo quelli dovrebbero far bloccare una recv che sia stata fatta solo dopo
un apposito select, come suggerivo) probabilmente non ha interfaccia
utente significativa, e la sua funzionalita` relativa alle socket e quanto
ci ruota attorno puo` costituire una frazione molto rilevante del tutto.
L'adozione di una libreria di threading (che rivesta le funzionalita` native
delle diverse piattaforme) puo` permettere, come gia` accennavo, di
ottenere la funzionalita` desiderata (interrompere una chiamata
bloccante dopo un periodo di timeout) in modo portabile (fra macchine
su cui sia implementata la libreria di threading stessa), con il semplice
accorgimento di lasciar bloccare solo un thread secondario, e ucciderlo
se il tempo scade prima che sia terminato.  Naturalmente anche questo
puo` dare dei problemi (ma interrompere una recv con un alarm puo`
darne almeno altrettanti, anche sul piu` puro dei BSD).
Alex

 wrote in message
news:vCsY3.62962$s17.6...@typhoon.libero.it...


 Un programma di server (chi altro DEVE gestire le socket in modo cosi`
Discordo. Anche un Web server non si limita alla gestione del traffico di
rete, anche se ovviamente è una parte importante. Certo che se realizzi un
time server, probabilmente la parte dei socket costituisce il 90% del
programma...
Per il resto, sono d'accordo con il tuo discorso, salvo il fatto che pure la
gestione dei thread mi risulta essere tutt'altro che standard.
--
Alessandro Monti

 Penso che utilizzero' una select! ;-)
La soluzione migliore, se sufficiente.  E` molto meglio 
dell'alarm che rompe la recv, anche su qualsiasi Unix.
Verifica anche, se occorre, la possibilita` di usare delle
socket non-bloccanti e/o con timeout implicito (le varie
funzioni setsockopt, ioctl, ioctlsocket, o fcntl, a seconda
dei sistemi in gioco, ti permettono di giocare con questi
parametri; non portabile al 100%, ad es. su vecchie
versioni di Unix System/V se e` una tua esigenza, pero`
la non-portabilita` e`, qui, facilmente incapsulabile).
Alex