SocketTimeoutException

no se si es la manera correcta pero configure en mi server un timeout de 20 segundos
y en mi cliente un timeout de 60 segundos cuando lse cumple el timeout de cliente lo que hago es socket.close y listo
en mi server hago lo mismo eso es correcto o hay que tener en cuenta otras consideraciones ya que mi server no respondera al cliente si lo deja pasar los 20 segundos y necesitaria una reconexion.

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de ezamudio

lectura

El socketTimeout es para lectura solamente. Es decir, en cuanto haces un   (en cualquiera de sus variantes), el hilo que invoca eso se bloquea pero si no recibe datos en el tiempo establecido, se arroja la excepción.

Así como lo configuraste, si el server lee datos en cuanto se conecta un cliente, entonces el cliente tiene 20 segundos para enviar datos. Y el server tiene 60 segundos para contestar (asumiendo que el cliente comienza a leer en cuanto termina de escribir).

Generalmente yo en el server pongo timeouts bastante más cortos, para evitar conexiones que se quedan abiertas porque alguien anda haciendo mapeo de puertos o telnets a lo loco. Si estás usando un protocolo síncrono pues en cuanto el cliente se conecta debe comenzar a escribir (o en cuanto el server le avise que está listo).

Está bien que el cliente tenga un timeout más amplio para darle tiempo al server de que conteste, pues generalmente tiene que atender a varios clientes al mismo tiempo.

ok..

esta es mi variante
 

quisiera saber si en el server se produce el timeout, debria cerrar socket.close????

tengo otra situacion y es que mi aplicacion son varios pestañas, en una de ellas es la que maneja lo de socket, cuando entro a esa pestaña hago conexion y mando peticion que me carga unas opciones y de ahi en adelante todo bien , solo que si la persona que maneja el programa deja pasar 20 segundos se produce el time out del server y el aplicativo deja de funcionar, si salgo y vuelvo a entrar a la pestaña no pasa nada ya que el validad que si socket!=null para volver a reconectar entonces 40 segundos despues se produce el timeout del lado del cliente que hago que me coloque socket.close y socket=null cuando salgo y vuelvo a entrar ya se me reconecta sin problema,

hay alguna manera de mejorar esta situacion???? donde estoy cometiendo el error??

por otro lado tu dices que colocas timeout bastantes pequeños, imaginate que el aplicativoes algo asi entro ala pestaña se conecta y me manda las opcines disponibles:
opcion 1
opcion 2
opcion 3
timeout(60s) timeout(20s)

------------------------------------------------------------------------------------>solicita opciones
clientes.......(800 o mas clientes)------------------------------------------------

entre las opciones que llegan el cliente selecciona una opcion (envia al server la opcion seleccionada)

-->manda opción seleccionada y el server responde una series de preguntas segun la opcion
clientes.......(800 o mas clientes)------------------------------------------------

-->ahora entre esa opciones selecciona las que quiera da enviar el server procesa y guadar en la base de datos y termina la
transaccion, (el terminar no lo hago manualmente si no por timeout se me desconecta) me imagino que seria mas optimo que el cliente terminara la conexion.

segun lo que te describi si el cliente tomara mas de 20 segundos que es el time out que esta en el server tonnces termina la transaccion a pensasr de que el cliente seleccione todo su test y le de enviar ya no recibe respuesta ya que el server sufio de timeout y desconecto.

si tu dices que tienes timeout re pequeños de cuanto??? en mi caso como evito esa situacion que mi cliente no termine el test?????

Imagen de ezamudio

cambia

Cambia tu protocolo. No veo por qué tienes que tener abierta una conexión entre cliente y servidor en lo que el usuario está pensando qué opción elegir; puede irse a comer si quiere y elegir algo cuando regrese, y la decisión se debe enviar al server usando una conexión distinta.

Cuando hago cosas de ese tipo yo pongo en el server un timeout de 3 a 5 segundos para dar tiempo a los clientes con conexiones lentas (celulares por ejemplo) de que envíen datos, pero son protocolos donde el cliente se conecta e inmediatamente empieza a enviar datos. Y sí, cuando se da timeout en el server, se cierra la conexión.

Así que tu app en el cliente debería conectarse al server, pedir opciones, recibirlas, desconectarse y mostrarlas; cuando el usuario elija una opción, abres una conexión nueva para enviar la decisión al server. Esto también es mejor para el server porque no tiene que mantener conexiones abiertas que ni siquiera tienen actividad y por lo tanto funcionará mejor el esquema del thread pool para despachar un gran número de conexiones efímeras.

ok

ya entiendo el manejo en mi caso lo que debo hacer es conectarse y pedir los temas al server, el cliente sin aun cerrar conexion debe selecionar el tema y el server le contestas las preguntas de ese tema, ahi ddebo desconectar cuando el cliente conteste las preguntas reconecto y envio las respuestas y el cliente cirra conexion.

mi imagino que en aplicativos...

donde se le da al cliente digamos 40 segundos para teminar el proceso, por ejemplo la venta de una loteria donde llega la persona a compar un boleto y el vendedor maximo de tiempo tiene 40 segundos o 60 segundos para terminar la venta,
me imagino que en ese caso si dejo la conexión abierta y trabajo desconexion por timeout o por final de la transacción.

gracias

ezamudio gracias por responder es bueno que un novato hable con un experto como vos, se abre mi mente y las ganas de cada dia aprender mas y mas simpelmente gracias.

timeout

ezamudio me salta una duda después de probar todo las sugerencias que hiciste y es que si en mi timeout del lado del servert tengo 20 segundos o menos y el del lado del cliente tengo 60 segundos al producir la excepción del lado del servidor y dar socket.close y socket=null para terminar la conexion, por el lado del cliente el ciclo infinito que el estaba ejecutando para recibir respuesta termina y ahí cierro mi conexión también, pero.............
el timeout del lado del cliente nunca se me dar???? ????

Imagen de ezamudio

eh?

Los timeouts se dan cuando haces una lectura. Tener un socket abierto así nada más no causa el timeout (lo puede cerrar el sistema operativo después de un tiempo de inactividad pero eso es aparte). Me parece que tu aplicación tiene un esquema de que el cliente se conecta y envía datos y espera una respuesta del server y luego el usuario tiene que hacer algo y luego el cliente envía datos nuevamente.

Estás haciendo esto con tus sockets:

- Cliente abre conexión
- Server acepta conexión
- Cliente establece timeout de lectura 60 segundos
- Server establece timeout de lectura 20 segundos

Con esa configuración, en el momento en que el server comience a leer datos del cliente (que debería ser en cuanto se recibe la conexión, no veo para qué esperar, aunque bueno podría estar encolada la conexión en un thread pool y no se lee nada hasta que le toque un hilo), esa lectura de datos bloqueará al hilo hasta por 20 segundos; si no llega nada, se arroja SocketTimeoutException y puedes ahí mismo cerrar la conexión.

Del lado del cliente, en el momento en que hagas una lectura de datos, el hilo se bloqueará hasta por 60 segundos y si no recibe nada en ese tiempo se arroja SocketTimeoutException.

Si asignas el socket a null o no, es irrelevante. Lo importante es que invoques  . Si vas a abrir un socket para una sesión en el cliente incluso puedes usar el try with resources:

 

Lo que yo sugería en mi comentario anterior era que no hagas todo en una conexión:

- Cliente abre conexión, envía unos datos, recibe respuesta, cierra conexión
- Muestra opciones al usuario, el usuario elige algo
- Cliente abre nuevamente conexión y envía elección del usuario al server, espera respuesta, cierra conexión

De esa manera las conexiones duran muy poco tiempo abiertas. Con tu esquema actual estás desperdiciando recursos en el server porque mantienes conexiones abiertas mientras esperas interacción de los usuarios del lado de los clientes.

pense....

simpre pense que una nueva conexion era mas costosa, claro que la idea la adquiri fue por programas esos datafonos en c, que su comunicacion era por simcard donde para una conexion y desconexion es realmente costoso, preferia dejar la conexion abierta siempre, y si solo la cerraba por inactivida.

aqui en la aplicacion que hize te cuento el proceso es simple mi cliente se comunica a mi server y desde mi server se comunica a un tercero solicitando los temas, lugo que consigo los temas selecciono uno y de ahi me devuelven unas 5 preguntas que se usuario debe responder y de ahi se termina toda la transaccion, eso solo lo hago en la misma conexion, por eso le di al server 40 segundos para que completara ese ciclo.

claro yo pido info me llega cierro conexion , hago lo que tengo que hacer y abro una nueva conexion y cierro, ya mi server se libera lo mas rapido posible y se ahorrar recursos excelente.

ahora funcionara igual de bien en un datafono esas maquinas donde tu pasa la tarjeta de credito, se porograman en c su comunicacion es por simcard no son 4g :( funcionara igual de bien???

la conexion del cliente ...

no se si es la mejor forma pero funciona o como lo harian ustedes???

 

Imagen de ezamudio

no

No entendí lo último (tampoco le pongo mucha atención al código que postean, no tengo mucho tiempo para estar leyendo esos ejemplos de código). Pero no habías mencionado lo de que la conexión sale por celular hasta ahora. No sé si es muy caro establecer una conexión, lo que sí sé es que al menos en México las conexiones de datos son malísimas y nada confiables, por lo que mantener una conexión abierta no sería para mí la mejor alternativa porque tienes que considerar que se puede caer en cualquier momento. Cuando he tenido que hacer algo así, tengo que incluir en el protocolo que puedan hacerse reenvíos parciales de respuestas (porque en mi caso las peticiones son cortas y las respuestas largas, pero si las peticiones son largas también habría que considerar reenvíos parciales de peticiones).