2012-06-26 5 views
6

Estoy aprendiendo a usar SO_SNDTIMEO y SO_RCVTIMEO para verificar el tiempo de espera. Es fácil de usar con leer socket. Pero cuando deseo verificar escribir el tiempo de espera, siempre regresa con éxito. Esto es lo que hice: (todo en modo de bloqueo)cómo simular un caso anormal para la programación de socket/tcp en Linux, como la terminación de un lado de la conexión?

  1. cerca el cliente lea toma de corriente y salida antes de que el inicio del servidor escritura
  2. rescindir el cliente antes de inicio del servidor escritura
  3. desenchufe el cable de servidor después de aceptar pero antes de escribir

bien, parece que todos estos casos escribe acaba de regresar con éxito. Creo que la razón debería ser que el puerto es administrado por el sistema operativo, y en el lado del cliente, una vez que el programa se ha ido, la conexión tcp todavía muestra FIN_WAIT2 estado.

es así, ¿hay alguna manera conveniente para simular algunos casos que escritura puede recibir errores como EPIPE, EAGAIN?

Respuesta

5

¿Cómo obtener el error EAGAIN?
Para obtener el error EAGAIN, debe utilizar Sockets sin bloqueo. Con los sockets sin bloqueo, debe escribir grandes cantidades de datos (y dejar de recibir datos del lado de los pares), de modo que su búfer de TCP interno se llene y devuelva este error.

¿Cómo obtener el error EPIPE?
Para obtener el error EPIPE, debe enviar una gran cantidad de datos después de cerrar el socket por el lado del interlocutor. Puede obtener más información sobre el error EPIPE de este SO Link. Hice una pregunta sobre Broken Pipe Error en el enlace proporcionado y la respuesta aceptada proporciona una explicación detallada. Es importante tener en cuenta que para obtener el error EPIPE debe haber establecido el parámetro flags de enviar a MSG_NOSIGNAL. Sin eso, un envío anormal puede generar señal SIGPIPE.

Nota adicional
Tenga en cuenta que es difícil simular un error de escritura, como TCP generalmente almacena los datos que usted está tratando de escribir en él es buffer interno. Entonces, si el buffer interno tiene suficiente espacio, entonces no obtendrá un error inmediatamente. La mejor manera es intentar escribir grandes cantidades de datos.También puede intentar configurar un tamaño de búfer más pequeño para enviar utilizando la función setsockopt con la opción SO_SNDBUF

+0

gracias por su información y lo intentaré. Para ** leer **, en realidad obtuve EAGAIN y EWOULDBLOCK en modo de bloqueo cuando se agota el tiempo de espera. Solo asumo que funciona igual cuando ** write ** timeout. – xgwang

1

Puede establecer que el tamaño del búfer de recepción sea realmente pequeño en un lado y envíe un búfer grande en el otro. O, por un lado, configure el búfer de envío como pequeño e intente enviar un mensaje grande.

De lo contrario, la prueba más común (creo) es dejar que el servidor y el cliente hablen durante un rato, y luego quitar un cable de red.

5

Puede simular errores utilizando fault injection. Por ejemplo, libfiu es una biblioteca de inyección de fallas que viene con un proyecto de ejemplo que le permite simular errores de las funciones de POSIX. Básicamente, utiliza LD_PRELOAD para inyectar un contenedor alrededor de las llamadas al sistema normal (incluido write), y luego el contenedor se puede configurar para que pase a la llamada al sistema real, o le devuelva el error que desee.

+0

gracias. Probablemente no sea lo que estoy buscando, pero la inyección de fallas parece interesante. Creo que puedo aprender a mejorar la cobertura del código. – xgwang

Cuestiones relacionadas