linux - scripts - socket() c
¿Leerá() alguna vez el bloque después de seleccionar()? (5)
En realidad, no debería bloquear (¡para eso es para lo que es select ()!), Pero de hecho, podría , excepcionalmente. Normalmente, read () debe devolver hasta el número máximo de bytes que haya especificado, lo que posiblemente incluya cero bytes (¡en realidad esto es algo válido!), Pero nunca debe bloquearse después de haber informado previamente de la disponibilidad.
Sin embargo, vea la página de select Linux:
Bajo Linux, select () puede reportar un descriptor de archivo de socket como "listo para leer", mientras que, sin embargo, es un bloque de lectura posterior. Esto podría suceder, por ejemplo, cuando han llegado los datos, pero al examinarlos tienen una suma de comprobación incorrecta y se descartan. Puede haber otras circunstancias en las que un descriptor de archivo se informe falsamente como listo. Por lo tanto, puede ser más seguro usar O_NONBLOCK en sockets que no deben bloquearse.
Estoy leyendo un flujo de datos a través de socket TCP / IP. La carga de la corriente es muy desigual. A veces, grandes cantidades de datos llegan cada segundo, a veces no hay datos durante una hora. En el caso de un largo período de inactividad (no hay datos del servidor remoto, pero la conexión aún está en línea) mi programa debería tomar algunas medidas.
Estoy implementando un tiempo de espera utilizando un select (). Me dice si hay datos listos, pero no sé exactamente cuánto puedo leer sin hacer que se bloquee read (). El bloqueo es inaceptable, ya que puede durar mucho más tiempo que el tiempo de espera que necesito.
En aras de la eficiencia, la secuencia se lee en un búfer grande y la llamada read () se proporciona con ese tamaño de búfer.
¿Leerá () el bloque después de seleccionar () si el búfer a llenar es mayor que la cantidad de datos disponibles ahora mismo en el socket?
Hay O_NONBLOCK
que se puede configurar por fcntl
/ F_SETFL
y debería dar como resultado una read
sin bloqueo.
No, read()
leerá hasta el tamaño especificado y devolverá los bytes reales leídos, que pueden ser menos.
Puede usar recv () que no se bloquea de forma predeterminada (si no se especifica el indicador MSG_WAITALL)
Un descriptor de archivo de bloqueo bloqueará en read () hasta que haya algo para leer, podría ser un byte o su solicitud completa. Un descriptor no bloqueante no se bloqueará en read () si no hay nada para leer. Select () no se lee (). Básicamente, pone el proceso en suspensión y supervisa el (los) descriptor (es) del archivo (s), incluidos los descriptores de no bloqueo. Cuando hay actividad en uno de los descriptores (o el período de tiempo de espera expira), seleccione devoluciones y puede leer sus datos, o hacer otra cosa en el caso del tiempo de espera.
Así que tienes dos problemas separados. (1) Desea "realizar algunas acciones" cuando no hay datos. Ese es el tiempo de espera seleccionado. (2) Una vez que tenga los datos (notificados por selección), no desea bloquearlos en una lectura. Ese es el modo de no bloqueo. Cuando obtiene EAGAIN en la lectura sin bloqueo, vuelve a la selección y / o "realiza algunas acciones" y vuelve a seleccionar.