Problema programación sockets

09/10/2007 - 09:43 por Francisco Matamoros | Informe spam
Buenas, estoy desarrollando una aplicación para comunicar una máquina de
expedición con un PC. La conexión es un diálogo a base de peticiones y
recepciones UDP. Utilizo la clase System.Net.Sockets haciendo uso de
UDPClient e IPEndPoint. A cada petición o recepción de datos, a la máquina
hay que enviarle confirmación mediante un <ACK>. Me ha surgido un problema
que paso a detallar gracias a la herramienta WireShark para ver paquetes de
red.

La máquina para que os hagáis una idea se utiliza para expedir artículos en
un almacén de expedición, se pide nº pedido, artículo, lote, unidades,
Todo esto se pide a través de un flujo continuo de instrucciones, siempre
igual lógicamente.
Si el diálogo es fluido, es decir, no hay tiempos de espera porque el
usuario de la máquina está constantemente introduciendo datos no tengo
ningún problema, pero si en alguna ocasión se detiene durante algunos
minutos la comunicación se pierde porque la máquina necesita siempre el
<ACK> de confirmación y me he encontrado con que en determinadas ocasiones
no se envía ese paquete.
Curiosamente cada vez que mi programa envía ese paquete y yo no lo veo
enviado (con wireshark se ve perfectamente) es porque justo detrás de la
recepción de un paquete de datos desde la máquina al PC, hay un paquete de
ARP en el que el PC pregunta quién es 192.168.0.84 (la máquina) y ésta le
responde, pero ya no veo el envío del <ACK> desde el PC a la máquina para
confirmarle el dato anterior. Pasando por el mismo punto del programa pero
con diálogo fluido si que se ven todos los paquetes enviados y recibidos
correctamente y el programa no se rompe.
Al principio del desarrollo sucedía algo parecido pero me di cuenta de que
si el firewall de Windows estaba activado, al pasar unos dos minutos sin
comunicación a a través del puerto UDP del PC (este puerto no lo escojo yo,
lo escoje siempre Windows), cerraba el puerto a la comunicación y la máquina
ya no encontraba el PC. Desactivando el firewall o poniendo una excepción al
ejecutable el problema se solucionó.

Muchas gracias y espero haberme explicado suficientemente claro para que
alguien sepa darme una idea de por donde van los tiros, o si podría utilizar
otra clase para programar la comunicación, o cómo lo haríais vosotros, en
fin, como véis estoy un poco desesperadillo, porque así no puedo entregar el
trabajo.
 

Leer las respuestas

#1 RFOG [MVP C++]
09/10/2007 - 09:54 | Informe spam
"Francisco Matamoros" wrote in message
news:
Buenas, estoy desarrollando una aplicación para comunicar una máquina de
expedición con un PC. La conexión es un diálogo a base de peticiones y
recepciones UDP. Utilizo la clase System.Net.Sockets haciendo uso de
UDPClient e IPEndPoint. A cada petición o recepción de datos, a la máquina
hay que enviarle confirmación mediante un <ACK>. Me ha surgido un problema
que paso a detallar gracias a la herramienta WireShark para ver paquetes
de red.

La máquina para que os hagáis una idea se utiliza para expedir artículos
en un almacén de expedición, se pide nº pedido, artículo, lote, unidades,
Todo esto se pide a través de un flujo continuo de instrucciones,
siempre igual lógicamente.
Si el diálogo es fluido, es decir, no hay tiempos de espera porque el
usuario de la máquina está constantemente introduciendo datos no tengo
ningún problema, pero si en alguna ocasión se detiene durante algunos
minutos la comunicación se pierde porque la máquina necesita siempre el
<ACK> de confirmación y me he encontrado con que en determinadas ocasiones
no se envía ese paquete.
Curiosamente cada vez que mi programa envía ese paquete y yo no lo veo
enviado (con wireshark se ve perfectamente) es porque justo detrás de la
recepción de un paquete de datos desde la máquina al PC, hay un paquete de
ARP en el que el PC pregunta quién es 192.168.0.84 (la máquina) y ésta le
responde, pero ya no veo el envío del <ACK> desde el PC a la máquina para
confirmarle el dato anterior. Pasando por el mismo punto del programa pero
con diálogo fluido si que se ven todos los paquetes enviados y recibidos
correctamente y el programa no se rompe.
Al principio del desarrollo sucedía algo parecido pero me di cuenta de que
si el firewall de Windows estaba activado, al pasar unos dos minutos sin
comunicación a a través del puerto UDP del PC (este puerto no lo escojo
yo, lo escoje siempre Windows), cerraba el puerto a la comunicación y la
máquina ya no encontraba el PC. Desactivando el firewall o poniendo una
excepción al ejecutable el problema se solucionó.

Muchas gracias y espero haberme explicado suficientemente claro para que
alguien sepa darme una idea de por donde van los tiros, o si podría
utilizar otra clase para programar la comunicación, o cómo lo haríais
vosotros, en fin, como véis estoy un poco desesperadillo, porque así no
puedo entregar el trabajo.





Hola.

Yo tengo varios proyectos diferentes que hablan por TCP (ninguna por UDP) y
no tengo ese problema, y a veces están horas conectadas sin hablarse entre
sí. Y encima por canales poco fiables, como GPRS. Pero yo lo hago de otra
forma (el código está en C++/CLI, pero pasarlo a C# es trivial):

void <clase>::OpenAndSendCommand()
{
int retry=0;
m_resultado=0;
while(retry<4)
{
try
{
m_socket=gcnew
Socket(AddressFamily::InterNetwork,SocketType::Stream,ProtocolType::Tcp);
m_socket->Connect(m_ipEndPoint);
break;
}
catch(SocketException ^)
{
delete m_socket;
retry++;
}
}
if(retry>=4)
{
m_resultado™9;
return;
}

retry=0;
while(retry<4)
{
try
{
// File::WriteAllBytes("D:\\projects\\cmd.txt",m_buffer);
m_socket->Send(m_buffer,0,m_messageLenght,SocketFlags::None);
break;
}
catch(Exception ^)
{
retry++;
}
}
if(retry>=4)
m_resultado™8;

// m_socket->Listen(1);
// m_socket->Accept();
}

La diferencia entre este código y el tuyo es que una vez que he terminado de
hablar cierro el canal, pero en otras aplicaciones (no puedo enseñar ese
código) se mantiene abierto sin problemas.
Microsoft Visual C++ MVP
==Visita mi blog principal: http://rfog.blogsome.com
Y este sobre programación: http://geeks.ms/blogs/rfog
Libros, ciencia ficción y programación
Respirar es un hábito. La vida es un hábito o, mejor dicho, una sucesión de
hábitos, ya que un individuo es una sucesión de individuos.

Preguntas similares