Newsgroup: it.comp.lang.visual-basic
Titolo: [Winsocket] Errore in fase di scollegamento dalla rete

Ciao a tutto il Ng, dopo tutto il pomeriggio che smazzo su google e sui
vostri post old non posso far altro che postare sul sito. Sono all'inizio di
testing di due applicazioni, la classica Client-Server che tramite il
winsock deve inviare/ricevere messaggi.
Tutto funziona correttamente tranne nel caso in cui il Client venga
scollegato dalla rete, il server non si accorge di questo e continua a
visualizzare la porta come aperta. Essendo il Client in rete wireless ed
installato su una ruspa, succede che a volte è coperto dalla rete, a volte
no. Quindi se il client si sconnette dalla rete il Server deve accorgersi e
liberare la porta (cosa che succede se riavvio il programma). Come posso
fare?
Ho installato Sp4 per motivi aziendali e non posso passare al Sp5.
Ho aggiornato il controllo winsock alla versione 6.0.88.4.
Grazie a tutti.
Ciao
p.s. Ho letto tutti i bug di winsock (allocare dinamicamente a run-time i
controlli winsock), di come M$ dice di ovviare al problema mettendo
LocalPort = 0 ???!!!.

*oZ* ci ha deliziati con queste righe
 Quote:
Scusa la risposta rapida : dal server non ti accorgi che il client ha perso
la rete, ma dal client si giusto ?
Mi spiego, dal client testi se sei in rete ( p.e. testi la porta del
server ) cosi il server lavorera' solo a comando del client !
un po contorto come metodo, ma credo sia la strada migliore in quanto il
server e' in listening fisso, quindi sta al client smazzarsi la connessione
e l'eventuale porta lasciata aperta, al server che inporta ?
-- 
<Gigio2K>
Sito Comune
Nokia -> I.T.H.N. -> 
http://www.ithn.it/
VB -> I.C.L.VB -> 
http://www.it-lang-vb.net/

Ho avuto lo stesso problema e l'ho risolto forse in maniera contorta e non
consona alle tue idee, ma visto che hai richiesto un parere ti fornisco
quello di un inesperto (cioè io). Questo metodo l'ho utilizzato per più
client verso un server e con un solo client funzionerà sicuramente (...le
ultime parole famose ). Nel connection_request del winsock del server associ
una variabile (es. rem_ip) in cui memorizzi l'ip remoto (cioè del client)
nel momento in cui si instaura la connessione. Utilizzi un controllo timer
con interval quello che vuoi tu (io uso 1000=1 sec) che controlla se il
winsock.remotehostip è uguale a quella variabile. Se la connessione è su il
client è visibile e ogni secondo gli restituisce l'ip, se il client è giù il
server non ottiene l'ip remoto e l'uguaglianza non si verifica. Ovviamente
dopo avergli fatto eseguire quel che vuoi (es. msgbox(il client è giù)
ricordati di resettare la variabile (es. rem_ip=""). Non sono stato molto
tecnico nella spiegazione, ma come si dice, il fine giustifica i mezzi !!
Ciao Max

 e l'eventuale porta lasciata aperta, al server che inporta ?
Intanto grazie della risposta, il problema č che il server č in listening
fisso, dal momento che la connessione si stabilisce tutto procede
regolarmente. Unico problema č quando il client perde la connessione alla
Rete: tramite il winsock non riesco piů a riconnettermi alla stessa porta
sul Server, anche chiudendo la connessione o  riallocando dinamicamente il
controllo.
Ciao
oZ

 tecnico nella spiegazione, ma come si dice, il fine giustifica i mezzi !!
No, anzi ti sei spiegato bene...
Quindi dal momento che trovo giů il client chiudo la porta e la riapro in
modo che il client possa riconnettersi?
Non capisco perchč un controllo cosě utile e carino debba avere sto ca@@o di
problema..Non esiste qualcosa in giro che tu sappia per evitare questo
workaround?
Grazie mille
ciao
oZ

 modo che il client possa riconnettersi?
scusa la domanda, ma se il server utilizza una matrice winsock, dove la zero
si occupa solo del listening e della connection, caricando di volta in volta
un nuovo controllo indice che si occupa dell'effettiva comunicazione, per
tornare poi in ascolto, non hai risolto tutti i problemi?
e poi, altra curiosita', che protocollo e che timeout usi per non renderti
conto se una connessione č ancora attiva?
beppe

 workaround?
il server lo lasci su (intendo in listening cioč state scklistening per la
precisione), semmai devi implementare il codice del client che, nel caso il
suo state sia diverso da sckconnected (7), deve chiudere il proprio socket e
ritentare l'evento connect. Quanto ad altre soluzioni ... non so, io sono
autodidatta in VB e come avrai visto poco tecnico come terminologia. Se
posso darti un piccolo consiglio, in fase di testing dedica, sia per il
server che per il client, una casella di testo dove farti scrivere tramite
un timer lo stato della connessione 'winsock.state'. Per altre info o qui o
via e-mail rimuovendo ogni cancelletto da #maxzerodue#@
tin.it

 controllo.
ma sai che adesso che rileggo meglio e' stranissima sta cosa?
cioe' e' il client che mantiene la porta del server come occupata
oppure sul server da "listening" rimane a "estabilish" ?
Se e' il secondo caso prevedi un timeout , tipo se entro 1 minuto non si
hanno messaggi dal client lo disconnetti ?
cmq mi sto impapocchiando se ho tempo faccio un po di prove per capire
meglio il probl !

 conto se una connessione è ancora attiva?
Uso il TCPProtocol, mentre per il timeout non utilizzo nessun controllo
timer..
Forse ho sbagliato l'approccio con il Winsocket (non è molto che lo
utilizzo, diciamo da ieri :)))
Il server usa 2 controlli Winsocket Sempre in Ascolto sulla porta es 4000 e
4001.
Esistono due client uno settato per comunicare sulla porta 4000 e l'altro
sulla 4001.
Facciamo l'esempio della connessione del client che utilizza la 4000.
Tramite il NetStat prima della connessione vedo :  porta 4000 e 4001 in
stato Listening.
Eseguo il Client 4000:
NetStat Porta 4000 remoto 0 in Listening e porta 4000 remoto xxxx
Established..
Se chiudo normalmente il Client parte l'evento del winsock_close del server
e quindi viene chiuso il socket, rimarrà la
porta 4000 remoto 0 in Listening
Se il client si scollega dalla rete non parte l'evento winsock_close del
server, anche se tramite netstat la connessione è effetivamente chiusa..
Se tento di ricollegarmi tramite il client ricevuto un errore..
Dov'è che sbaglio?
Grazie a tutti..
Ciao
oZ

> e poi, altra curiosita', che protocollo e che timeout usi per non renderti



Dov'è che sbaglio?
Grazie a tutti..
Ciao
oX

 utilizzo, diciamo da ieri :)))
partendo con un solo socket, una soluzione la si puo' schematizzare cosě:
lato server:
supponendo che l'indice 0 sia sempre in ascolto e che lanci gli altri indici
socket per la comunicazione,
nell'evento:
Sub Wsck_ConnectionRequest(Index As Integer, ByVal requestID As Long)
    static nuovoindice as integer
    nuovoindice=nuovoindice+1
'carichi un nuovo socket
    load wsck(nuovoindice)
    wsck(0).close
'accetti la connessione sul nuovo socket
    wsck(nuovoindice).accept requestID
'ti rimetti in ascolto
    wsck(0).listen
a questo punto quando dal lato client testi l'avvenuta connessione inizi la
trasmissione.
ora rimane l'organizzazione del tuo protocollo di comunicazione:
chi deve parlare per primo (in questo caso il client che valida l'avvenuta
connessione)
i codici di risposta, i tempi di timeout, la ricerca degli indici
disponibili per i socket del server ecc. ecc.
in una struttura cosě organizzata devi pero', nella pratica, gestire tutta
la trasmissione all'interno dell'evento dataarrival, e questa potrebbe
essere vista come una limitazione.
beppe

     wsck(0).listen
Grazie
Ciao
oZ

 Dov'è che sbaglio?
ti affidi al netstat e non al winsock.state ^_^
in pratica non usare il netstat ma usa la proprieta' .state del winsock che
ti resttuisce appunto lo stato del controllo e cmq io userei un arrai
dinamico di winsock cosi non devi preoccuparti se la porta X e' rimasta
occupata !


 Perchè in questo punto devi chiudere l'indice zero?
per poter accettare la connessione con il controllo a matrice nuovoindice e
rimettere in ascolto il controllo a matrice indice zero.
in questo modo sulla porta server che ti interessa hai enne elementi che
comunicano e uno che e' sempre in ascolto.
beppe

> *oZ* ci ha deliziati con queste righe
Deliziati ???? :))
Grazie a tutti delle risposte...
Farò delle prove come mi avete consigliato e se avrò altri dubbi posterò
ancora...
Ciao
oZ