Criar artificialmente um erro de tempo limite de conexão


291

Ocorreu um erro em nosso software que ocorre quando recebo um tempo limite de conexão. Esses erros são muito raros (geralmente quando minha conexão é interrompida por nossa rede interna). Como posso gerar esse tipo de efeito artificialmente para testar nosso software?

Se isso importa, o aplicativo é escrito em C ++ / MFC usando as classes CAsyncSocket.

Editar:

Eu tentei usar um host inexistente e recebo o erro de soquete:

WSAEINVAL (10022) Argumento inválido

Minha próxima tentativa foi usar a sugestão de Alexander de conectar-se a uma porta diferente, por exemplo, 81 (no meu próprio servidor). Isso funcionou muito bem. Exatamente o mesmo que uma conexão descartada (espera de 60 segundos e erro). Obrigado!


Olá Mark, Tentei a solução que funcione para você, mas o que estou recebendo é o número 503 (Serviço indisponível). Não deve ser um destes, # 504 (Tempo limite do gateway), # 599 (erro de tempo limite de conexão à rede), # 598 (erro de tempo limite de leitura da rede).
CoDe

Respostas:


297

Conecte-se a um host existente, mas a uma porta bloqueada pelo firewall que simplesmente descarta pacotes TCP SYN. Por exemplo, www.google.com:81.


6
Esta resposta é simples e funciona exatamente como a resposta do @ emu abaixo. Entendo que esta resposta não pretendia sugerir o uso de google.com:81, mas o objetivo aqui é usar uma porta diferente que esteja bloqueada. Portanto, você sempre pode usar <your-own-ip>: <blocked-port>.
James Selvakumar

6
A menos que seja seu próprio servidor, é rude atingir outros servidores para o seu teste. Use uma solução civilizada como a emu mencionada abaixo, acessando um endereço IP não roteável como 10.255.255.1 ou configure um servidor virtual próprio para fins de teste.
zeeshan

2
Eu acho que o Google pode ter bloqueado essa porta. Ao testar isso com o Chrome, apenas "Servidor não disponível". Quando uso o truque do @ emu abaixo, a conexão trava conforme o esperado. Estou esquecendo de algo?
entpnerd

O OP diz que ele se conectou à porta 81 em seu próprio servidor e conseguiu o tempo limite. Isso funcionou para mim também. A solução da emu me deu uma UnknownHostException no Android.
Barry Fruitman

2
Isso dará uma conexão recusada, sem tempo limite.
Mehdi

425

Conecte-se a um endereço IP não roteável, como 10.255.255.1.


12
Idem, e acho que essa é uma resposta melhor, pois o google.com:81 pode ser acessado um dia.
Gui13

138
... e porque enviar pacotes aleatórios para os servidores de outras pessoas a partir de seus testes de unidade é rude.
perfil completo de Glenn Maynard

15
Isso nem sempre funciona. Por exemplo, no Python urllib, isso retornará uma exceção 'No route to 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 estes não são roteáveis.
rajesh_kw

4
O erro "Sem rota para hospedar" mencionado por @FHI geralmente aparece em duas condições: (a) quando você tenta se conectar a um host não acessível na LAN local (ou seja, ele não responde às consultas ARP, é basicamente um " ARP timeout "). E (b) quando um roteador retorna o erro ICMP correspondente. O primeiro caso acontece se você estiver na mesma sub-rede que o IP privado que você testar. O segundo caso, se um roteador não souber rotear seu pacote para seu destino, mas em alguns casos eles simplesmente descartam o pacote sem enviar o erro ICMP.
Ale

47

Se você estiver em uma máquina unix, poderá iniciar uma porta escutando usando o netcat:

nc -l 8099

Em seguida, modifique seu serviço para chamar o que geralmente faz para essa porta, por exemplo, http: // localhost: 8099 / some / sort / of / endpoint

Em seguida, seu serviço abrirá a conexão e gravará dados, mas nunca receberá uma resposta e, portanto, fornecerá um Tempo limite de leitura (em vez de Conexão recusada)


1
É útil, pois você pode ver os dados que seu aplicativo está enviando. Você pode verificar se o seu aplicativo está solicitando uma resposta.
Paul

Isso é verdade para navegar para algum tipo de terminal, como mencionado, mas se eu tentar conectar-me de alguma outra maneira, ela rapidamente recusará uma conexão, que não é o comportamento que estou tentando zombar agora.
AlanSE

@ AlanSE - que outra maneira você quer dizer? Você pode ter qualquer coisa após o número da porta; netcat não vai se importar, uma vez que não tem nada a lidar com quaisquer URLs
Tom Chamberlain

@ TomChamberlain Oh, espere, talvez eu saiba o que estava fazendo de errado. Estou tentando simular um tempo limite de conexão ssh. Então, eu estou dando a ele localhost, porta 8099, mas anteriormente eu não fornecia um nome de usuário; portanto, se eu colocar alguma coisa ssh alanse@localhost -p 8099, parece que sim.
AlanSE

7
Para testar um tempo limite de conexão no nível do soquete, congele o processo nc com um kill -STOP <pid>(ou apenas CTRL-Z sem colocar em segundo plano). O sistema agirá como se o servidor estivesse em execução, mas aguarde o servidor aceitar a conexão, resultando em um tempo limite de conexão (erro 110).
Philant

27

O URL a seguir sempre dá um tempo limite e combina o melhor das respostas de @Alexander e @ Emu acima:

http://example.com:81

O uso example.com:81é uma melhoria na resposta de Alexander, porque o example.com é reservado pelo padrão DNS, portanto, sempre será inacessível, ao contrário google.com:81, o que pode mudar se o Google quiser. Além disso, como example.comé definido como inacessível, você não estará inundando os servidores do Google.

Eu diria que é uma melhoria em relação à resposta do @ emu porque é muito mais fácil de lembrar.


2
atualmente vejo a example.comresolução para 93.184.216.34 e, na verdade, serve um HTML curto, explicando que é um domínio de exemplo ... a porta 81 ainda não responde.
Beni Cherniavsky-Paskin

A questão é realmente se o example.com deve ser usado dessa maneira. Somente se eles tornarem oficialmente livres para serem inundados com pacotes de teste esse domínio é melhor do que qualquer outro domínio comercial. Usar domínios para esse fim sem permissão é antiético, para dizer o mínimo, se não ilegal, porque está custando dinheiro a alguém para lidar com esses pacotes. Considere usar httpstat.uscomo @AndyTheEntity apontado em sua resposta.
Manuel

@ Manuel Você está perdendo o objetivo ... example.comnão é um domínio comercial, é um dos poucos nomes de domínio que são explicitamente especificados como inutilizáveis. Ninguém pode possuir example.come os roteadores DNS sabem que ele nunca é roteado para um endereço real. Portanto, não está custando tempo para ninguém, não há nada errado em usá-lo
speedplane

@speedplane A IANA é proprietária do domínio por regulamento e mantém um servidor da Web que fornece uma página da Web que explica o objetivo example.com. Há infra-estrutura por trás do domínio, portanto, cada solicitação está custando o dinheiro da IANA. O uso permitido é mencionado nas RFC 2606 e RFC 6761; você não é livre para usar os domínios para qualquer finalidade que desejar, como floddingeles, em vez de outro servidor, como você mencionou. Sua reivindicação example.com is defined to be unreachableincorreta, é alcançável. A porta 81 está inacessível agora, mas onde isso está definido para ser garantido no futuro?
Manuel

O RFC para o qual você aponta especificamente permite testes de DNS. Eles recomendam que você use um .testdomínio de nível superior, em vez de example.com, mas esses domínios foram claramente configurados para esse fim. Sim, pode custar à IANA um pouco de dinheiro, mas este é um serviço que eles fornecem. Nossas taxas de DNS estão pagando por isso.
speedplane

23

Muitas respostas boas, mas a solução mais limpa parece ser esse serviço

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

Você pode configurar a duração do tempo limite (até 230 segundos) e o eventual código de retorno.


16

Você pode usar o Python REPL para simular um tempo limite ao receber dados (ou seja, após uma conexão ter sido estabelecida com sucesso). Nada além de uma instalação padrão do Python é necessário.

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()

Agora aguarda uma conexão de entrada. Conecte o que você deseja testar localhost:9000. Quando você o fizer, o Python aceitará a conexão e accept()a retornará. A menos que você envie dados através do clientsocket, o soquete do chamador deve atingir o tempo limite durante o próximo recv().


Não funciona para mim; algo está faltando. Talvez s.listen(5)antes s.accept()?
bmaupin

@ bmaupin Isso parece razoável, acho que acabei de esquecer isso. Editado agora (no entanto, com uma fila de pendências 0), obrigado!
Henrik Heimbuerger 01/09/2015

1
Consegui colocar as partes de escuta e aceitação em um while True:loop, e isso parece ser um bom destino de tempo limite durável a ser atingido nos testes.
AlanSE 01/07

2
Ele funciona, mas dá erro "tempo limite de leitura", que não é o mesmo que "tempo limite de conexão"
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 estes não são roteáveis.


2
(Como eu comentei a resposta aceita) Quando testei um XMLHttpRequest no Node.js, as conexões 10.0.0.0e 10.255.255.255acionamos um erro EACCES em vez de atingir o tempo limite. 10.255.255.1, 172.16.0.0, 172.31.255.255, 192.168.0.0, E 192.168.255.255fez tempo limite, no entanto.
Jamie Birch

9

Eu gostaria de chamar a atenção de todos para o pathod

Com uma configuração (tirada de seus exemplos), 200:b@100:drvocê obtém uma conexão que cai aleatoriamente.


1
Não é o mesmo que um tempo limite
dentarg 08/12/16

8

Que tal uma solução de software:

Instale o servidor SSH no servidor de aplicativos. Em seguida, use o socket tunnel para criar um link entre a porta local e a porta remota no servidor de aplicativos. Você pode usar ferramentas de cliente ssh para fazer isso. Faça com que seu aplicativo cliente se conecte à sua porta local mapeada. Em seguida, você pode quebrar o túnel do soquete à vontade para simular o tempo limite da conexão.


4

Se você deseja usar uma conexão ativa, também pode usar http://httpbin.org/delay/# , em que # é o tempo que você deseja que o servidor espere antes de enviar uma resposta. Contanto que o tempo limite seja menor que o atraso ... deve simular o efeito. Eu usei com sucesso com o pacote de pedidos python.

Convém modificar sua solicitação se estiver enviando algo confidencial - não faço ideia do que acontece com os dados enviados a eles.


Max 10 segundos embora (Se você colocar em um número maior ele vai responder depois de 10 segundos)
Harry Madeira

2

Existem serviços disponíveis que permitem criar artificialmente tempos limite de origem chamando uma API na qual você especifica quanto tempo o servidor levará para responder. O tempo limite do servidor no macgyver é um exemplo desse serviço.

Por exemplo, se você quiser testar uma solicitação que leva 15 segundos para responder, basta fazer uma solicitação de postagem à API do macgyver.

Carga JSON:

{
    "timeout_length": 15000
}

Resposta da API (após 15 segundos):

{
    "response": "ok"
}

Programa de tempo limite do servidor no macgyver
https://askmacgyver.com/explore/program/server-timeout/3U4s6g6u


1

Você pode instalar o driver Microsoft Loopback que criará uma interface separada para você. Em seguida, você pode conectar-se a algum serviço seu (seu próprio host). Em Conexões de rede, você pode desativar / ativar essa interface ...


1

Apesar de não estar completamente claro qual deles o OP deseja testar: há uma diferença entre tentar uma conexão com um host / porta inexistente e o tempo limite de uma conexão já estabelecida. Eu iria com Rob e esperaria até que a conexão estivesse funcionando e depois puxaria o cabo. Ou - por conveniência - tenha uma máquina virtual funcionando como servidor de teste (com rede em ponte) e desativando a interface de rede virtual assim que a conexão for estabelecida.


1

A técnica usada com freqüência para simular um tempo limite de conexão aleatória é usar o encaminhamento de porta local ssh.

ssh -L 12345:realserver.com:80 localhost

Isso encaminhará o tráfego no localhost: 12345 para realserver.com:80. Você também pode fazer um loop na própria máquina local, se desejar:

ssh -L 12345:localhost:8080 localhost

Portanto, você pode apontar seu aplicativo para o host local e a porta personalizada, e o tráfego será roteado para o host de destino: port. Em seguida, você pode sair deste shell (também pode ser necessário pressionar Ctrl + c depois de sair) e isso eliminará o encaminhamento que faz com que o aplicativo veja uma perda de conexão.


0

Conecte o cabo de rede a um switch que não possui outra conexão / cabos. Isso deve funcionar imho.


0

Existem algumas táticas que usei no passado para simular problemas de rede;

  1. Retire o cabo de rede
  2. Desligue o interruptor (idealmente, com o interruptor em que o computador está conectado ainda está sendo alimentado, para que a máquina mantenha sua "conexão de rede") entre sua máquina e a máquina "alvo"
  3. Execute o software de firewall na máquina de destino que descarta silenciosamente os dados recebidos

Uma dessas idéias pode fornecer alguns meios de gerar artificialmente o cenário necessário


0

Dependendo do software de firewall que você instalou / disponível, você poderá bloquear a porta de saída e, dependendo de como o seu firewall estiver configurado, ele deverá apenas eliminar o pacote de solicitação de conexão. Sem solicitação de conexão, sem conexão, o tempo limite segue. Provavelmente, isso funcionaria melhor se fosse implementado no nível do roteador (eles tendem a soltar pacotes em vez de enviar redefinições, ou qualquer que seja o equivalente para a situação), mas certamente haverá um pacote de software que também funcionaria.


0

O mais fácil seria interromper sua conexão usando o CurrPorts .

No entanto, para testar seu código de manipulação de exceções, talvez você deva abstrair seu código de conexão de rede e escrever um esboço, simulação ou decorador que lança exceções sob demanda. Você poderá testar a lógica de tratamento de erros do aplicativo sem precisar usar a rede.


Com o CurrPorts, parece que só consigo fechar a conexão (o que faz com que o próximo recv()falhe imediatamente), mas não consegui encontrar uma maneira de simular um tempo limite (ou seja, não há mais dados transferidos, mas a conexão permanece aberta).
Henrik Heimbuerger

Apreciei esta resposta por sugerir um teste de unidade que zomba de exceções de conexão sob demanda.
Danny Bullis

0

Eu tive problemas nas mesmas linhas que você. Para testar o comportamento do software, acabei de desconectar o cabo de rede no momento apropriado. Eu tive que definir um ponto de interrupção antes de querer desconectar o cabo.

Se eu estivesse fazendo isso de novo, colocaria um comutador (um botão momentâneo normalmente fechado) em um cabo de rede.

Se a desconexão física causar um comportamento diferente, você poderá conectar seu computador a um hub barato e colocar o comutador mencionado acima entre o hub e a rede principal.

- EDIT - Em muitos casos, você precisará da conexão de rede funcionando até chegar a um determinado ponto do seu programa; então, você poderá desconectar usando uma das muitas sugestões oferecidas.


0

Para mim, a maneira mais fácil foi adicionar rota estática no roteador do escritório com base na rede de destino. Apenas direcione o tráfego para algum host que não responda (por exemplo, o seu computador) e você receberá o tempo limite da solicitação.

A melhor coisa para mim foi que a rota estática pode ser gerenciada através da interface da web e ativada / desativada facilmente.


-1

Você pode tentar se conectar a um dos sites conhecidos em uma porta que pode não estar disponível externamente - 200 por exemplo. A maioria dos firewalls funciona no modo DROP e simula um tempo limite para você.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.