• Martes 12 de Noviembre de 2024, 20:57

Autor Tema:  Cerrar y reabrir un socket  (Leído 3066 veces)

diego.martinez

  • Miembro MUY activo
  • ***
  • Mensajes: 297
    • Ver Perfil
Cerrar y reabrir un socket
« en: Miércoles 22 de Septiembre de 2010, 18:04 »
0
Buenas:

Tengo una aplicación que escucha un puerto UDP por un puerto (digamos que 10000) y que envia los datos tratados por otro puerto TCP digamos el 10001.
Son Sockets non-blocking. Uso el FD_SET y el select para saber si tienen datos de entrada o salida para enviar y recibir.

Todo funciona correctamente, pero cuando finalizo las conexiones, al intentar reabrir de nuevo, me encuentro con problemas.
El socket TCP se queda en un estado en el que nunca tiene forma de escribir y siempre lee 0 bytes.
El select siempre me da como que tiene para leer, pero no para escribir.

Si hago netstat -ano en el equipo, me encuentro que los sockets no han sido eliminados sino que estan en TIME_WAIT y encima hay multiples sockets conectados de la misma forma.

el finalizado del socket lo hago con

shutdown()
y luego
closesocket()

son sockets en WIN32.
Código: C++
  1.  
  2. int W32SOCKET_TCP::Close()
  3. {
  4.     this->State=GSOCKET::STATE::KILLING;
  5.     shutdown(this->ID,2);
  6.     return  closesocket(this->ID);   //ID es el identificador de SOCKET
  7. }
  8.  
  9.  

que estoy haciendo mal? por que no se finalizan los sockets para que pueda volverlos a abrir?

PD: no estoy usando multitarea. Uso una función Poll para enviar y recibir segun el estado del select.

gracias!

Epa

  • Miembro MUY activo
  • ***
  • Mensajes: 242
  • Nacionalidad: ar
    • Ver Perfil
Re: Cerrar y reabrir un socket
« Respuesta #1 en: Martes 28 de Septiembre de 2010, 03:51 »
0
buenas.

Cuando cerras un socket no se puede volver a abrir en seguida de nuevo, segun dicen por razones de seguridad.

Proba usar esto en lugar del shutdown:

DisconnectEx(this->ID, NULL, TF_REUSE_SOCKET, 0);

Saludos
The sweet smell of a great sorrow lies over the land.


diego.martinez

  • Miembro MUY activo
  • ***
  • Mensajes: 297
    • Ver Perfil
Re: Cerrar y reabrir un socket
« Respuesta #2 en: Martes 28 de Septiembre de 2010, 15:55 »
0
gracias, pero me pasa algo curioso

incluyo Mswsock.h pero me sigue dando

error C3861: 'DisconnectEx': identifier not found, even with argument-dependent lookup

he puesto tambien la WINVER a 0x0500 por si acaso pero sigue dandome el mismo fallo, en msdn no pone nada al respecto. ¿Que tengo que hacer?

diego.martinez

  • Miembro MUY activo
  • ***
  • Mensajes: 297
    • Ver Perfil
Re: Cerrar y reabrir un socket
« Respuesta #3 en: Miércoles 13 de Octubre de 2010, 16:03 »
0
buenas

Ya he conseguido poner las extensiones de winsock y poder usar el DisconnectEx

sin embargo, cuando lo ejecuto me bloquea la aplicación durante todo el tiempo del time_wait (varios minutos)

en la documentacion lo dice:

Note  The socket level disconnect is subject to the behavior of the underlying transport. For example, a TCP socket may be subject to the TCP TIME_WAIT state, causing the DisconnectEx call to be delayed.

hay alguna solucion a esto?

gracias!

Epa

  • Miembro MUY activo
  • ***
  • Mensajes: 242
  • Nacionalidad: ar
    • Ver Perfil
Re: Cerrar y reabrir un socket
« Respuesta #4 en: Lunes 18 de Octubre de 2010, 14:27 »
0
Es genial, esos de micro$oft te dan una solucion con un nuevo problema.

La verdad que no se una solucionar el bloqueo, pero podrias crear un hilo para llamar a la funcion, cosa que se bloquee ese hilo y el programa siga corriendo.

No creo que sea lo ideal, pero puede que funcione.

Saludos
The sweet smell of a great sorrow lies over the land.


diego.martinez

  • Miembro MUY activo
  • ***
  • Mensajes: 297
    • Ver Perfil
Re: Cerrar y reabrir un socket
« Respuesta #5 en: Lunes 18 de Octubre de 2010, 19:30 »
0
si. parece que la espera es inevitable. Por suerte, he visto que solo se produce en el socket cliente, asi que si el cliente desconecta correctamente, la finalización del server es inmediata.

gracias!