Hola, estoy tratando de detectar en la aplicación cliente, cuando el servidor se ha desconectado. En la documentación MSDN dice que si el host remoto cierra la conexión y ya no quedan datos por enviar, entonces este método va a devolver cero bytes.
Trato de aprovechar esta información de la siguiente manera:
Dim Answer As Integer = 0
Do
'Realizo todas las tareas pertinentes de lectura
'En especial:
Answer = Stream.Read(BufferRead, 0, BufferRead.Length)
Loop While Answer > 0
RaiseEvent HostDisconnected()
Lo que pasa es que la variable Answer me guarda el número de los últimos bytes leídos, y nunca me devuelve 0. Por ejemplo, cuando cierra la conexión el servidor, Answer siempre me devuelve el número 61, por lo que nunca se puede salir del bucle y lanzar el evento HostDisconnected().
Entonces lo que hago es agarrar la excepción que se produce cuando no se puede ejecutar el método Read del stream porque no hay un host remoto conectado, y le asigno 0 a la variable. De esa forma me sale del bucle y me lanza el evento. Pero no lo veo muy seguro, porque si se presenta cualquier otra excepción al momento de ejecutar este método, que nada tenga que ver con la desconexión del host, entonces me va a salir como que el host se desconectó, lo cual no sería cierto.
La otra salida que le encuentro es crear una clase propia que herede de System.Net.Sockets.NetWorkStream y así usar la propiedad Socket que me devuelve el socket asociado con el stream. De esta forma el bucle se haría de una manera más simple, algo así como:
While MyStreamClass.Socket.Connected
'Hacer las tareas de escucha
End While
'Lanzar el evento
Pero prefiero no hacer eso y tratar de sacarlo mediante esta forma, ya que quiero mantener este código lo más simple posible.
Por si a alguien le interesa un poco más el código, este es:
PrivateSub Read()
Dim BufferReader() AsByte
Dim Answer AsInteger = 0
Do
BufferReader = NewByte(TcpClient.ReceiveBufferSize) {}
Try
Answer = Stream.Read(BufferReader, 0, BufferReader.Length())
Dim XmlStringReceived AsString = Encoding.UTF8.GetString(BufferReader)
If XmlStringReceived.StartsWith("<Event") Then
Dim XmlParser AsNew XmlParser(XmlStringReceived, False)
RaiseEvent ClientConnected(XmlParser.IpClientConnected,
XmlParser.NicknameClientConnected, XmlParser.EventClass)
Else
Dim XmlParser AsNew XmlParser(XmlStringReceived, True)
MsgBox(XmlStringReceived, MsgBoxStyle.Information, "Aplicación cliente:
Mensaje recibido por parte del servidor")
RaiseEvent MessageReceived(XmlParser.Message, XmlParser.IpFrom,
XmlParser.Nickname)
EndIf
Catch Ex As Exception
Answer = 0
EndTry
MsgBox(Answer)
LoopWhile Answer > 0
RaiseEvent HostDisconnected()
Thread.Abort()
EndSub
Saludos a todos.