Una escritura en un zócalo también puede bloquear, especialmente si es un zócalo TCP. El sistema operativo solo almacenará una cierta cantidad de datos no transmitidos (o transmitidos, pero no reconocidos). Si escribe cosas más rápido de lo que la aplicación remota puede leerlas, el socket eventualmente realizará una copia de seguridad y sus llamadas write
se bloquearán.
responder a estas preguntas de seguimiento:
Entonces, ¿hay un mecanismo para establecer un tiempo de espera para esto? No estoy seguro de qué comportamiento hubiera tenido ... ¿tal vez tirar datos si los buffers están llenos? ¿O posiblemente borrar datos más antiguos en el búfer?
No hay ningún mecanismo para configurar un tiempo de espera de escritura en java.net.Socket. Hay un método Socket.setSoTimeout()
, pero afecta a accept()
y read()
llamadas ... y no a write()
llamadas. Aparentemente, puedes obtener tiempos de espera de escritura si usas NIO, modo sin bloqueo y Selector, pero esto no es tan útil como podrías imaginar.
Una pila TCP correctamente implementada no descarta datos almacenados a menos que la conexión esté cerrada. Sin embargo, cuando obtiene un tiempo de espera de escritura, no está claro si los datos que se encuentran actualmente en los búferes de nivel de sistema operativo han sido recibidos por el otro extremo ... o no. El otro problema es que no sabe cuánto de los datos de su último write
se transfirió realmente a los búferes de pila TCP de nivel del sistema operativo. En ausencia de algún protocolo de nivel de aplicación para resincronizar la secuencia *, lo único seguro después de un tiempo de espera en write
es cerrar la conexión.
Por el contrario, si utiliza una toma UDP, las llamadas write()
no se bloquearán durante un período de tiempo significativo. Pero la desventaja es que si hay problemas de red o la aplicación remota no se mantiene, los mensajes se dejarán caer sin notificación a ninguno de los extremos. Además, puede encontrar que los mensajes a veces se entregan a la aplicación remota fuera de servicio. Depende de usted (el desarrollador) lidiar con estos problemas.
* Teóricamente es posible hacerlo, pero para la mayoría de las aplicaciones no tiene sentido implementar un mecanismo de resincronización adicional sobre una transmisión TCP/IP ya confiable (hasta un punto). Y si tuviera sentido, también necesitaría tratar con la posibilidad de que la conexión se cerrara ... por lo que sería más simple asumir que cerró.
El hecho de que no es una característica de tiempo de espera no es en sí una indicación de que no bloquee. Una indicación de que lo hace es la falta de un valor de retorno: si no bloquea, ¿por qué no devuelve el número de bytes realmente escritos? Otra indicación se da simplemente intentándolo. – EJP