Buenos dias.
Tengo que conectar mi programa a una máquina y lo hago de forma asincrona.
La máquina hace de servidor, así que yo tengo que conectar con ella
siempre que este arrancada.
Mi problema es que cuando apagan la máquina no se lanza ninguna
excepción y mi programa se queda
esperando a recibir datos indefinidamente de una conexión que ya no existe.
Me hace falta recoger la desconexión cuando se produce para reiniciar el
proceso de comunicación. No me vale hacer ping porque el host se puede
apagar y encender en muy pocos segundos.
Este es mi código principal:
public void Conectar()
{
try
{
tcpClient = new TcpClient(ip.ToString(),puerto);
tcpClient.ReceiveBufferSize24;
tcpClient.ReceiveTimeoute;
networkStream=tcpClient.GetStream();
buff = new byte[1024];
cbRead = new AsyncCallback(CuandoLecturaCompleta);
//<-Preparo la conexión
if(eventoEstadoConexion!=null)
eventoEstadoConexion(true);
ComenzarALeer(); //<-Comienzo la conexión
}
catch(System.Net.Sockets.SocketException se)
{
if(eventoError!=null)
eventoError(se,"Host inaccesible");
}
catch(Exception se)
{
if(eventoError!=null)
eventoError(se,"Excepción preparando la conexión");
}
}
private void ComenzarALeer() //<=Empezar a leer de forma asincrona
{
try
{
//Cuando se reciben datos esto los manda a la función
'CuandoLecturaCompleta'.
//En caso de que la máquina se desconecte nunca mas
recibe nada la función
// 'CuandoLecturaCompleta', pero tampoco se lanza
ninguna excepción
iasync=networkStream.BeginRead(buff,0,buff.Length,cbRead,null);
}
catch(Exception se)
{
if(eventoError!=null)
eventoError(se,"Excepción comenzando a leer");
}
}
private void CuandoLecturaCompleta( IAsyncResult ar)
{
try
{
int bytesRead = networkStream.EndRead(ar);
if ( bytesRead > 0)
{
string s =
System.Text.Encoding.ASCII.GetString(buff, 0, bytesRead);
//Aqui enviamos los datos mediante el evento en
caso de que haya sido instanciado
if(eventoDatosRecibidos!=null)
eventoDatosRecibidos(s.Substring(0,bytesRead));
ComenzarALeer(); //Seguimos leyendo
}
else
{
//Se ha cortado la conexión
CerrarConexion();
if(eventoEstadoConexion!=null)
eventoEstadoConexion(false);
}
}
catch(System.IO.IOException se)
{
CerrarConexion();
if(eventoEstadoConexion!=null)
eventoEstadoConexion(false);
}
catch(Exception se)
{
if(eventoError!=null)
eventoError(se,"Excepción recibiendo mensaje");
}
} //CuandoLecturaCompleta
Cuando comenzé el desarrollo, la comunicación la realizaba de forma
sincrona y cuando el host se desconectaba recibía un mensaje vacio. El
problema era que me comía todos los recursos de la máquina, ya que tengo
que estar continuamente mirando si hay nuevos mensajes.
¿Alguien sabe como recoger el evento de desconexión del host con este
tipo de comunicación?
Un Saludo
Leer las respuestas