Crear artificialmente un error de tiempo de espera de conexión

291

He tenido un error en nuestro software que ocurre cuando recibo un tiempo de espera de conexión. Estos errores son muy raros (por lo general, cuando mi conexión se cae por nuestra red interna). ¿Cómo puedo generar este tipo de efecto artificialmente para poder probar nuestro software?

Si es importante, la aplicación está escrita en C ++ / MFC usando clases CAsyncSocket.

Editar:

Intenté usar un host inexistente y recibí el error de socket:

WSAEINVAL (10022) Argumento no válido

Mi siguiente intento fue utilizar la sugerencia de Alexander de conectarse a un puerto diferente, por ejemplo, 81 (aunque en mi propio servidor). Eso funcionó muy bien. Exactamente lo mismo que una conexión perdida (60 segundos de espera, luego error). ¡Gracias!

Mark Ingram
fuente
Hola Mark, probé una solución que funciona para ti, pero lo que estoy recibiendo es el # 503 (Servicio no disponible). No debería ser uno de estos, # 504 (Tiempo de espera de la puerta de enlace), # 599 (Error de tiempo de espera de conexión de red), # 598 (Error de tiempo de espera de lectura de red).
Código de

Respuestas:

297

Conéctese a un host existente pero a un puerto que esté bloqueado por el firewall que simplemente descarta los paquetes TCP SYN. Por ejemplo, www.google.com:81.

Alejandro
fuente
66
Esta respuesta es simple y funciona igual que la respuesta de @emu a continuación. Entiendo que esta respuesta no tenía la intención de sugerir el uso de google.com:81, pero el punto aquí es usar un puerto diferente que esté bloqueado. Por lo tanto, siempre puede usar <your-own-ip>: <blocked-port>.
James Selvakumar
66
A menos que sea su propio servidor, es grosero golpear a otros servidores para su prueba. Use una solución civilizada como la que se menciona a continuación, presionando una dirección IP no enrutable como 10.255.255.1, o configure un servidor virtual propio para fines de prueba.
zeeshan
2
Creo que Google puede haber bloqueado este puerto. Cuando pruebo esto con Chrome, simplemente "Servidor no disponible". Cuando uso el truco de @emu a continuación, la conexión se bloquea como se esperaba. ¿Me estoy perdiendo de algo?
entpnerd
El OP dice que se conectó al puerto 81 en su propio servidor y obtuvo el tiempo de espera. Eso me funcionó a mí también. La solución de emu me dio una UnknownHostException en Android.
Barry Fruitman
2
Esto dará una conexión rechazada, no tiempo de espera.
Mehdi
425

Conéctese a una dirección IP no enrutable, como 10.255.255.1.

emú
fuente
12
Idem, y supongo que esta es una mejor respuesta ya que google.com:81 podría ser accesible algún día.
Gui13
138
... y porque enviar paquetes aleatorios a los servidores de otras personas desde las pruebas unitarias es grosero.
Glenn Maynard
15
Esto no siempre funcionará. Por ejemplo, con Python urllib, esto devolverá una excepción 'Sin ruta al host'. FYI
Mike Shultz
8
10.0.0.0, 10.255.255.255, 172.16.0.0, 172.31.255.255, 192.168.0.0, 192.168.255.255 todos estos no son enrutables.
rajesh_kw
44
El error "Sin ruta al host" mencionado por @FHI generalmente aparece en dos condiciones: (a) cuando intenta conectarse a un host no accesible en su LAN local (lo que significa que no responde las consultas ARP, por lo que es básicamente un " Tiempo de espera ARP "). Y (b) cuando un enrutador devuelve el error ICMP correspondiente. El primer caso ocurre si está en la misma subred que la IP privada que prueba. El segundo caso si un enrutador no sabe cómo enrutar su paquete a su destino, pero en algunos casos simplemente lo sueltan sin enviar el error ICMP.
Ale
47

Si está en una máquina Unix, puede comenzar a escuchar un puerto usando netcat:

nc -l 8099

Luego, modifique su servicio para llamar a lo que normalmente hace a ese puerto, por ejemplo, http: // localhost: 8099 / some / sort / of / endpoint

Luego, su servicio abrirá la conexión y escribirá datos, pero nunca recibirá una respuesta, por lo que le dará un Tiempo de espera de lectura (en lugar de Conexión rechazada)

Tom Chamberlain
fuente
1
Es útil ya que puede ver los datos que su aplicación está empujando. Puede verificar si su aplicación solicita una respuesta.
Paul
Esto es cierto para navegar a algún tipo de punto final, como se mencionó, pero si trato de conectarme de otra manera, rápidamente da una conexión rechazada, que no es el comportamiento que estoy tratando de burlar en este momento.
AlanSE
@AlanSE: ¿de qué otra manera te refieres? Puede tener cualquier cosa después del número de puerto; A netcat no le importará, ya que no tiene nada para manejar ninguna URL
Tom Chamberlain
@ TomChamberlain Oh, espera, podría saber lo que estaba haciendo mal. Estoy tratando de simular un tiempo de espera de conexión ssh. Así que le estoy dando localhost, puerto 8099, pero anteriormente no le di un nombre de usuario, así que si solo pongo algo ssh alanse@localhost -p 8099, parece que lo hace.
AlanSE
77
Para probar un tiempo de espera de conexión a nivel de socket, congele el proceso nc con un kill -STOP <pid>(o simplemente CTRL-Z sin poner en segundo plano). El sistema actuará como si el servidor se estuviera ejecutando, pero espere a que el servidor acepte la conexión, lo que dará como resultado un tiempo de espera de conexión (error 110).
frágil
27

La siguiente URL siempre da un tiempo de espera y combina lo mejor de las respuestas de @Alexander y @ Emu anteriores:

http://example.com:81

El uso example.com:81es una mejora en la respuesta de Alexander porque example.com está reservado por el estándar DNS, por lo que siempre será inalcanzable, a diferencia de lo google.com:81que puede cambiar si Google lo desea. Además, debido a que example.comse define como inalcanzable, no estará inundando los servidores de Google.

Diría que es una mejora con respecto a la respuesta de @emu porque es mucho más fácil de recordar.

Speedplane
fuente
2
Actualmente veo example.comresolviendo 93.184.216.34, y en realidad sirve un breve HTML explicando que es un dominio de ejemplo ... el puerto 81 todavía no responde.
Beni Cherniavsky-Paskin
La pregunta es si se supone que example.com debe usarse de esa manera. Solo si hacen que sea oficialmente libre de ser inundado con paquetes de prueba, este dominio es mejor que cualquier otro dominio comercial. Usar dominios para tal propósito sin permiso no es ético, por decir lo menos, si no ilegal, porque le está costando dinero a alguien manejar estos paquetes. Considere usar httpstat.uscomo @AndyTheEntity señaló en su respuesta.
Manuel
@Manuel Te estás perdiendo el punto ... example.comno es un dominio comercial, es uno de los pocos nombres de dominio que se especifica explícitamente como inutilizable. Nadie puede ser propietario example.comy los enrutadores DNS saben que nunca se enruta a una dirección real. Así que no le cuesta a nadie el tiempo del servidor, no hay nada de malo en usarlo
speedplane
@speedplane La IANA posee el dominio por regulación y mantiene un servidor web que proporciona una página web que explica el propósito de example.com. Hay infraestructura detrás del dominio, por lo tanto, cada solicitud le está costando dinero a la IANA. El uso permitido se menciona en RFC 2606 y RFC 6761, no es libre de usar los dominios para el propósito que desee, como floddingellos en lugar de otro servidor, como usted menciona. Su reclamo que example.com is defined to be unreachablees incorrecto, es accesible. El puerto 81 es inalcanzable ahora, pero ¿dónde se define eso para garantizarlo en el futuro?
Manuel
El RFC al que apunta específicamente permite la prueba de DNS. Recomiendan usar un .testdominio de nivel superior, en lugar de example.com, pero estos dominios se configuraron claramente para este propósito. Sí, puede costarle un poco de dinero a la IANA, pero este es un servicio que brindan. Nuestras tarifas de DNS lo están pagando.
Speedplane
23

Muchas buenas respuestas, pero la solución más limpia parece ser este servicio

http://httpstat.us/504?sleep=60000

Puede configurar la duración del tiempo de espera (hasta 230 segundos) y el código de retorno eventual.

AndyTheEntity
fuente
16

Puede usar Python REPL para simular un tiempo de espera mientras recibe datos (es decir, después de que una conexión se haya establecido con éxito). Solo se necesita una instalación estándar de Python.

Python 2.7.4 (default, Apr  6 2013, 19:54:46) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import socket
>>> s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)        
>>> s.bind(('localhost', 9000))
>>> s.listen(0)
>>> (clientsocket, address) = s.accept()

Ahora espera una conexión entrante. Conecta lo que quieras probar localhost:9000. Cuando lo haga, Python aceptará la conexión y la accept()devolverá. A menos que envíe datos a través de clientsocket, el zócalo de la persona que llama debe expirar durante el siguiente recv().

Henrik Heimbuerger
fuente
No funciona para mi algo falta, algo está faltando. Quizás s.listen(5)antes s.accept()?
bmaupin
@bmaupin Eso suena razonable, supongo que lo olvidé. Editado ahora (sin embargo, con una cola de 0), ¡gracias!
Henrik Heimbuerger
1
Pude poner las partes de escuchar y aceptar en un while True:bucle, y eso parece ser un buen destino de tiempo de espera duradero para probar.
AlanSE 01 de
2
Funciona, pero da error "tiempo de espera de lectura", que no es lo mismo que "tiempo de espera de conexión"
Timur
13
  • 10.0.0.0
  • 10.255.255.255
  • 172.16.0.0
  • 172.31.255.255
  • 192.168.0.0
  • 192.168.255.255

Todos estos no son enrutables.

rajesh_kw
fuente
2
(Como he comentado sobre la respuesta aceptada) Cuando probé una XMLHttpRequest en Node.js, las conexiones 10.0.0.0y 10.255.255.255dispararon un error EACCES en lugar de agotar el tiempo de espera. 10.255.255.1, 172.16.0.0, 172.31.255.255, 192.168.0.0, Y 192.168.255.255lo hizo de tiempo de espera, sin embargo.
Jamie Birch
9

Me gustaría señalar la atención de todos al método

Con una configuración (tomada de sus ejemplos) 200:b@100:drobtendrás una conexión que cae aleatoriamente.

amenthes
fuente
1
No es lo mismo que un tiempo de espera
dentarg el
8

¿Qué tal una solución de software:

Instale el servidor SSH en el servidor de aplicaciones. Luego, use el túnel de socket para crear un enlace entre su puerto local y el puerto remoto en el servidor de aplicaciones. Puede usar las herramientas de cliente ssh para hacerlo. Haga que su aplicación cliente se conecte a su puerto local asignado en su lugar. Luego, puede romper el túnel del zócalo a voluntad para simular el tiempo de espera de la conexión.

Stoneboy
fuente
4

Si desea usar una conexión activa, también puede usar http://httpbin.org/delay/# , donde # es el tiempo que desea que su servidor espere antes de enviar una respuesta. Mientras su tiempo de espera sea más corto que el retraso ... debería simular el efecto. Lo he usado con éxito con el paquete de solicitudes de Python.

Es posible que desee modificar su solicitud si está enviando algo confidencial; no tengo idea de qué sucede con los datos que se les envían.

RoHS4U
fuente
Sin embargo, máximo 10 segundos (si ingresa un número mayor, responderá después de 10 segundos)
Harry Wood
2

Hay servicios disponibles que le permiten crear artificialmente tiempos de espera de origen llamando a una API donde especifique cuánto tiempo tardará el servidor en responder. Server Timeout en macgyver es un ejemplo de dicho servicio.

Por ejemplo, si desea probar una solicitud que tarda 15 segundos en responder, simplemente haga una solicitud posterior a la API de macgyver.

Carga JSON:

{
    "timeout_length": 15000
}

Respuesta API (después de 15 segundos):

{
    "response": "ok"
}

Programa de tiempo de espera del servidor en macgyver
https://askmacgyver.com/explore/program/server-timeout/3U4s6g6u

Timothy Moody
fuente
1

Puede instalar el controlador Microsoft Loopback que creará una interfaz separada para usted. Luego puedes conectarte a algún servicio tuyo (tu propio host). Luego, en Conexiones de red, puede deshabilitar / habilitar dicha interfaz ...

Marcin Gil
fuente
1

A pesar de que no está completamente claro cuál es el OP que quiere probar: hay una diferencia entre intentar una conexión a un host / puerto inexistente y un tiempo de espera de una conexión ya establecida. Iría con Rob y esperaría hasta que la conexión funcionara y luego tiraría del cable. O, por conveniencia, tener una máquina virtual que funcione como servidor de prueba (con conexión en red en puente) y que simplemente desactive la interfaz de red virtual una vez que se establezca la conexión.


fuente
1

La técnica que uso con frecuencia para simular un tiempo de espera de conexión aleatorio es usar el reenvío de puerto local ssh.

ssh -L 12345:realserver.com:80 localhost

Esto reenviará el tráfico en localhost: 12345 a realserver.com:80. También puede recorrer esto en su propia máquina local, si desea:

ssh -L 12345:localhost:8080 localhost

Para que pueda apuntar su aplicación a su puerto local y puerto personalizado, y el tráfico se enrutará al host de destino: puerto. Luego puede salir de este shell (es posible que también necesite presionar ctrl + c el shell después de salir) y eliminará el reenvío, lo que hace que su aplicación vea una pérdida de conexión.

jdi
fuente
0

Conecte su cable de red a un conmutador que no tenga otra conexión / cables. Eso debería funcionar en mi humilde opinión.

GHad
fuente
0

Hay un par de tácticas que he usado en el pasado para simular problemas de redes;

  1. Tire del cable de red
  2. Apague el interruptor (idealmente con el interruptor en el que la computadora está enchufada aún encendida para que la máquina mantenga su "conexión de red") entre su máquina y la máquina "objetivo"
  3. Ejecute el software de firewall en la máquina de destino que descarta silenciosamente los datos recibidos

Una de estas ideas podría darle algunos medios para generar artísticamente el escenario que necesita

Robar
fuente
0

Dependiendo del software de firewall que haya instalado / disponible, debería poder bloquear el puerto de salida y dependiendo de cómo esté configurado su firewall, simplemente debería descartar el paquete de solicitud de conexión. Sin solicitud de conexión, sin conexión, se produce el tiempo de espera. Esto probablemente funcionaría mejor si se implementara a nivel de enrutador (tienden a descartar paquetes en lugar de enviar restablecimientos, o lo que sea equivalente para la situación), pero seguramente habrá un paquete de software que también funcionaría.

Matthew Scharley
fuente
0

Lo más fácil sería dejar su conexión usando CurrPorts .

Sin embargo, para probar su código de manejo de excepciones, quizás debería considerar abstraer su código de conexión de red y escribir un código auxiliar, simulador o decorador que arroje excepciones a pedido. Entonces podrá probar la lógica de manejo de errores de la aplicación sin tener que usar la red.

Matt Howells
fuente
Con CurrPorts, parece que solo puedo cerrar la conexión (lo que hace que el siguiente recv()falle inmediatamente), pero no pude encontrar una manera de simular un tiempo de espera (es decir, no se transfieren más datos, pero la conexión permanece abierta).
Henrik Heimbuerger
Aprecié esta respuesta por sugerir una prueba unitaria que se burla de las excepciones de conexión a pedido.
Danny Bullis
0

Tuve problemas en la misma línea que tú. Para probar el comportamiento del software, simplemente desconecté el cable de red en el momento apropiado. Tuve que establecer un punto de interrupción justo antes de querer desconectar el cable.

Si lo volviera a hacer, pondría un interruptor (un botón momentáneamente normalmente cerrado) en un cable de red.

Si la desconexión física causa un comportamiento diferente, puede conectar su computadora a un concentrador barato y colocar el interruptor que mencioné anteriormente entre su concentrador y la red principal.

- EDITAR: en muchos casos, necesitará que la conexión de red funcione hasta que llegue a un cierto punto en su programa, ENTONCES querrá desconectarse utilizando una de las muchas sugerencias que se ofrecen.

Brad Bruce
fuente
0

Para mí, la forma más fácil fue agregar una ruta estática en el enrutador de la oficina según la red de destino. Simplemente enrute el tráfico a algún host que no responda (por ejemplo, su computadora) y obtendrá el tiempo de espera de la solicitud.

Lo mejor para mí fue que la ruta estática se puede administrar a través de la interfaz web y habilitar / deshabilitar fácilmente.

Ivan Marjanovic
fuente
-1

Puede intentar conectarse a uno de los sitios web conocidos en un puerto que puede no estar disponible desde el exterior: 200 por ejemplo. La mayoría de los firewalls funcionan en modo DROP y simulará un tiempo de espera para usted.

Dmitry Khalatov
fuente