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.

Preguntas similare

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.
Respuesta Responder a este mensaje
#2 Francisco Matamoros
09/10/2007 - 10:32 | Informe spam
Gracias por responder tan pronto.
Voy a intentarlo de ese modo, ¿qué ocurre que UDP es más "flojo" que TCP? La
verdad nunca programé comunicaciones y utilicé lo primero que ví sin
preocuparme mucho más de lo necesario.

En cuanto lo tenga reporto comentarios.
Saludos.

"RFOG [MVP C++]" escribió en el mensaje
news:
"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.


Respuesta Responder a este mensaje
#3 RFOG [MVP C++]
09/10/2007 - 10:47 | Informe spam
"Francisco Matamoros" wrote in message
news:
Gracias por responder tan pronto.
Voy a intentarlo de ese modo, ¿qué ocurre que UDP es más "flojo" que TCP?
La verdad nunca programé comunicaciones y utilicé lo primero que ví sin
preocuparme mucho más de lo necesario.

En cuanto lo tenga reporto comentarios.
Saludos.

"RFOG [MVP C++]" escribió en el mensaje
news:
"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.
irlandés.










Hasta donde yo sé (y sin mirar documentación), sí. Si no me equivoco, el UDP
es para envío de pocos paquetes y de poca duración. El TCP es más robusto y
es capaz de mantener la conexión mejor (No he mirado nada de la
documentación, así que podría ser justo al revés, o incluso no ser cierto,
pero por lo que recuerdo la última vez que lo miré, creo que es así).


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.
Respuesta Responder a este mensaje
#4 Jose Luis Manners
09/10/2007 - 14:49 | Informe spam
Hola Francisco,

porque no usas TCP en lugar de UDP? TCP te mantiene la conexión y la
entrega de los paquetes es mas garantizada. Yo normalmente uso UDP para
enviar mensajes masivos (broadcast), los cuales no requieren mantener una
conexión.

-
Coopera con el foro. Dinos si te sirvió la respuesta aquí planteada.
-

Regards/Saludos,

Jose Luis Manners
Microsoft MVP Visual C#
http://www.josemanners.com/

"Simplicity is the ultimate sophistication."




"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.


Respuesta Responder a este mensaje
#5 Alfredo Novoa
09/10/2007 - 23:01 | Informe spam
On Tue, 9 Oct 2007 10:32:36 +0200, "Francisco Matamoros"
wrote:

Gracias por responder tan pronto.
Voy a intentarlo de ese modo, ¿qué ocurre que UDP es más "flojo" que TCP?



UDP no garantiza la entrega de los paquetes de datos. Se suele usar
para cosas en las que no importe perder algunos datos como voz IP,
video, etc.

Si no quieres que se pierdan paquetes lo normal es usar TCP.

La
verdad nunca programé comunicaciones y utilicé lo primero que ví sin
preocuparme mucho más de lo necesario.



Parece que te has preocupado menos de lo necesario ;-)

Antes de elegir tienes que mirar un poco las características de cada
protocolo.


Saludos
Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente Respuesta Tengo una respuesta
Search Busqueda sugerida