Oppure

Loading
01/07/09 17:01
rickysac
Ciao a tutti! sto creando un semplice programmino di chat client/server con Visual Studio 2008 (linguaggio di programmazione Visual Basic). Il programma funziona discretamente bene tuttavia ho alcuni problemi nella chiusura delle connessioni. Ho messo un pulsante che permette direttamente di chiudere la connessione attiva e, ad ogni modo, questa deve chiudersi quando ovviamente si esce dalla finestra della conversazione.
Per interderci meglio posto un po' di codice:

server:
listener = New TcpListener(IPAddress.Any, port)
listener.Start()
client = listener.AcceptTcpClient()
str = client.GetStream
writer = New StreamWriter(str)
reader = New StreamReader(str)

client:
client.Connect(addr, port) 'addr è ovviamente l'indirizzo
str = client.GetStream() 'crea il flusso di dati
writer = New StreamWriter(str)
reader = New StreamReader(str)

dopo che la connessione è attiva client o server possono scrivere messaggi e periodicamente ognuno controlla se ce ne sn nel buffer e li scrive in una label.

writer.WriteLine(stringa)
stringa = reader.ReadLine()

il problema si ha quando client o server chiudono la connessione
ho creato una subroutine che chiude la connessione e resetta le impostazioni, tuttavia dall'altro lato questo non avviene, dunque in un qualche modo l'applicazione deve capire che il collegamento non c'è più e deve smettere di inviare/ricevere messaggi.

la mia soluzione è stata di mettere una try-exception quando si inviano o ricevono i messaggi, in pratica se si ha un eccezione vuol dire che la connessione non è più attiva.
il metodo funziona ma solo in un verso! se chiudo il server il client al primo tentativo di lettura capisce che si è disconnesso e chiude tutto, mentre il server non riesce a capire che il client si è disconnesso.
in pratica rimane lì bloccato e non si sblocca finche non faccio terminare il client, a quel punto segnala correttamente che la connessione è caduta e riparte

temo che il problema sia nella stringa = reader.ReadLine() che, essendo bloccante, blocca il computer, tuttavia nel lato client questa lancia normalmente la sua exception e va avanti, non capisco perchè il server invece rimanga congelato.
dunque stavo pensando di verificare prima dell'invio/ricezione peridodico se la connessione è ancora attiva, ma nn saprei come fare
ho provato a fare una if client.connected tuttavia mi da una nullpointerexception (anche se evidentemente il client esiste perchè la connessione funziona) nel client e nel server ad ogni modo non funziona (semplicemente ignora l'if)
qualcuno mi ha consigliato di mandare periodicamente un messaggio tipo "sono connesso", può essere un idea ma nn risolve il problema nel caso di cadute "vere" della connessione e crashs, qualcuno ha idee please?
in particolare rimangono perplesso sulla non funzionalità della client.connect!

nota aggiuntiva: può essere che la client.connect non funzioni perchè faccio tutto in locale?
Ultima modifica effettuata da rickysac 01/07/09 17:06
aaa
01/07/09 18:53
GoLDBeRG
prova a ricavare il socket dal tcplistener e dallo stream e a fare if sock.connected=false then......
aaa
02/07/09 6:55
rickysac
In effetti facendo client.Client si raggiungono interessanti funzioni, però rimango perplesso. Non ho trovato uno strumento diretto per il socket
Per gli altri che ho provato accade questo: client.Client.connected da sempre true dopo aver effettuato la connect (dunque continua ad essere vero anche dopo ke da una delle due parti mi sono disconnesso e ho chiuso la connessione) ho provato anche altre utili funzioni tipo canwrite, canread o avaible ma queste invece danno sempre false (che è ovviamente impossibile perchè intanto trasferisco senza problemi). Veramente nn riesco a capire, ripeto non è che il problema sta nel fatto che uso i due programmi in locale?
aaa
02/07/09 7:46
GoLDBeRG
            If us.client.EndReceive(ar) < 1 Then
                disconnettiuser(us)
                Exit Sub
            End If


questo per quanto riguarda la disconnessione del client da parte del server.... se invece cade il server il client per capire che è disconnesso il server... prova a fare cosi...

Dim buffer() As Byte = Encoding.Default.GetBytes(data)
            Module1.impostazioni.banda += buffer.Length
            Module1.protocol.byteinviati += buffer.Length
            Try
                us.stream.Write(buffer, 0, buffer.Length)
                us.stream.Flush()
            Catch
                disconnettiuser(us)
            End Try
aaa
02/07/09 21:10
rickysac
Grazie della dritta ma esattamente cos'è ar? Come hai visto io nn uso una connessione ascincrona con sockets...
aaa
08/07/09 7:24
GoLDBeRG
bene vediamo..... hai il while sia da parte del server che da parte del client dovendo sia restare in ascolto che ricevere dati...
metti un try nel read sia del client che del server se uno va in errore vuol dire che l'altro si è disconnesso.... dovresti poterti regolare cosi
aaa