Creare artificialmente un errore di timeout della connessione


291

Ho avuto un bug nel nostro software che si verifica quando ricevo un timeout di connessione. Questi errori sono molto rari (di solito quando la mia connessione viene interrotta dalla nostra rete interna). Come posso generare artificialmente questo tipo di effetto in modo da poter testare il nostro software?

Se è importante, l'app è scritta in C ++ / MFC usando le classi CAsyncSocket.

Modificare:

Ho provato a utilizzare un host inesistente e ottengo l'errore socket:

WSAEINVAL (10022) Argomento non valido

Il mio prossimo tentativo fu di usare il suggerimento di Alexander di collegarmi a una porta diversa, ad esempio 81 (sul mio server però). Ha funzionato alla grande. Esattamente come una connessione interrotta (60 secondi di attesa, quindi errore). Grazie!


Ciao Mark, ho provato una soluzione che funziona per te ma quello che sto ricevendo è # 503 (servizio non disponibile.). Non dovrebbe essere uno di questi, # 504 (Timeout gateway), # 599 (Errore di timeout di connessione di rete), # 598 (Errore di timeout di lettura di rete).
CoDe

Risposte:


297

Connettersi a un host esistente ma a una porta bloccata dal firewall che elimina semplicemente i pacchetti TCP SYN. Ad esempio, www.google.com:81.


6
Questa risposta è semplice e funziona proprio come la risposta di @ emu di seguito. Comprendo che questa risposta non intendeva suggerire di utilizzare google.com:81, ma il punto qui è utilizzare una porta diversa che è bloccata. Quindi puoi sempre usare <your-own-ip>: <blocked-port>.
James Selvakumar,

6
A meno che non sia il tuo server, è scortese colpire altri server per i tuoi test. Usa una soluzione civile come quella emu sotto menzionata, colpendo un indirizzo IP non instradabile come 10.255.255.1 o imposta un tuo server virtuale a scopo di test.
Zeeshan,

2
Penso che Google potrebbe aver bloccato questa porta. Quando provo questo con Chrome, ho solo "Server non disponibile". Quando uso il trucco di @ emu di seguito, la connessione si blocca come previsto. Mi sto perdendo qualcosa?
entpnerd

L'OP afferma che si è collegato alla porta 81 sul proprio server e ha ottenuto il timeout. Questo ha funzionato anche per me. La soluzione di emu mi ha dato una UnknownHostException su Android.
Barry Fruitman,

2
Questo darà una connessione rifiutata non timeout.
Mehdi,

425

Connettersi a un indirizzo IP non instradabile, ad esempio 10.255.255.1.


12
Idem, e immagino che questa sia una risposta migliore poiché google.com:81 potrebbe essere raggiungibile un giorno.
Gui13,

138
... e poiché l'invio di pacchetti casuali ai server di altre persone dai test delle unità è scortese.
Glenn Maynard,

15
Questo non funzionerà sempre. Ad esempio, con Python's urllib, questo restituirà un'eccezione 'No route to host'. Cordiali saluti
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 tutti questi non sono instradabili.
rajesh_kw,

4
L'errore "No route to host" menzionato da @FHI appare generalmente in due condizioni: (a) quando si tenta di connettersi a un host non raggiungibile nella propria LAN locale (ovvero, non risponde alle query ARP, quindi è sostanzialmente un " Timeout ARP "). E (b) quando un router restituisce l'errore ICMP corrispondente. Il primo caso si verifica se ci si trova nella stessa sottorete dell'IP privato testato. Il secondo caso se un router non sa come instradare il pacchetto verso la sua destinazione, ma in alcuni casi semplicemente rilascia il pacchetto senza inviare l'errore ICMP.
Ale

47

Se sei su una macchina unix, puoi avviare una porta in ascolto usando netcat:

nc -l 8099

Quindi, modifica il tuo servizio per chiamare qualunque cosa faccia normalmente a quella porta, ad es. Http: // localhost: 8099 / some / sort / of / endpoint

Quindi, il tuo servizio aprirà la connessione e scriverà i dati, ma non riceverà mai una risposta, e quindi ti darà un timeout di lettura (anziché connessione rifiutata)


1
È utile poiché puoi vedere tutti i dati inviati dall'applicazione. È possibile verificare se l'applicazione richiede una risposta.
Paolo,

Questo è vero per la navigazione verso una sorta di endpoint, come detto, ma se provo a connettermi in un altro modo dà rapidamente una connessione rifiutata, che non è il comportamento che sto cercando di deridere in questo momento.
AlanSE,

@AlanSE - che altro modo intendi? Puoi avere qualsiasi cosa dopo il numero di porta; A Netcat non importa perché non ha nulla per gestire alcun URL
Tom Chamberlain,

@ TomChamberlain Oh aspetta, potrei sapere cosa stavo facendo di sbagliato. Sto cercando di simulare un timeout della connessione ssh. Quindi gli sto dando localhost, porta 8099, ma in precedenza non avevo dato un nome utente, quindi se ho appena inserito qualcosa ssh alanse@localhost -p 8099, sembra che lo faccia.
AlanSE,

7
Per testare un timeout di connessione a livello di socket, congela il processo nc con un kill -STOP <pid>(o semplicemente CTRL-Z senza metterlo in background). Il sistema funzionerà come se il server fosse in esecuzione, ma attenderà che il server accetti la connessione, determinando un timeout della connessione (errno 110).
filante

27

Il seguente URL fornisce sempre un timeout e combina le migliori risposte @Alexander e @ Emu sopra:

http://example.com:81

L'utilizzo example.com:81è un miglioramento della risposta di Alexander perché example.com è riservato dallo standard DNS, quindi sarà sempre irraggiungibile, diversamente google.com:81, che potrebbe cambiare se Google ne avesse voglia. Inoltre, poiché example.comè definito non raggiungibile, non invaderai i server di Google.

Direi che è un miglioramento rispetto alla risposta di @ emu perché è molto più facile da ricordare.


2
attualmente vedo che si sta example.comrisolvendo in 93.184.216.34, e in realtà serve un breve HTML che spiega che è un dominio di esempio ... la porta 81 non risponde ancora.
Beni Cherniavsky-Paskin,

La domanda è davvero se example.com dovrebbe essere usato in quel modo. Solo se lo rendono ufficialmente libero di essere invaso da pacchetti di test, questo dominio è migliore di qualsiasi altro dominio commerciale. L'uso di domini a tale scopo senza autorizzazione non è etico, per non dire altro, se non illegale, perché costa a qualcuno soldi per gestire questi pacchetti. Prendi in considerazione l'uso httpstat.uscome indicato da @AndyTheEntity nella sua risposta.
Manuel,

@Manuel Ti manca il punto ... example.comnon è un dominio commerciale, è uno dei pochi nomi di dominio che è stato esplicitamente specificato come inutilizzabile. Nessuno può possederlo example.come i router DNS sanno che non si dirige mai verso un indirizzo reale. Quindi non sta costando tempo a nessuno per il server, non c'è niente di sbagliato nell'usarlo
speedplane

@speedplane La IANA è proprietaria del dominio per regolamento e gestisce un server Web che fornisce una pagina Web che spiega lo scopo di example.com. C'è un'infrastruttura dietro il dominio, quindi ogni richiesta costa il denaro IANA. L'uso consentito è indicato in RFC 2606 e RFC 6761, non sei libero di utilizzare i domini per qualsiasi scopo ti piaccia, come floddingloro invece di un altro server, come dici. Il tuo reclamo example.com is defined to be unreachablenon è corretto, è raggiungibile. La porta 81 non è raggiungibile ora, ma dov'è che sarà definita per essere garantita in futuro?
Manuel,

L'RFC da te indicato consente in modo specifico i test DNS. Ti raccomandano di usare un .testdominio di livello superiore, piuttosto che example.com, ma questi domini sono stati chiaramente configurati per questo scopo. Sì, potrebbe costare un po 'di denaro allo IANA, ma questo è un servizio che forniscono. Le nostre tariffe DNS stanno pagando per questo.
speedplane

23

Molte buone risposte ma la soluzione più pulita sembra essere questo servizio

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

È possibile configurare la durata del timeout (fino a 230 secondi) e l'eventuale codice di ritorno.


16

È possibile utilizzare Python REPL per simulare un timeout durante la ricezione dei dati (ovvero dopo che una connessione è stata stabilita correttamente). Nient'altro che un'installazione standard di Python è necessaria.

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

Ora attende una connessione in entrata. Connetti qualunque cosa tu voglia testare localhost:9000. Quando lo fai, Python accetterà la connessione e accept()la restituirà. A meno che non si invii alcun dato tramite il clientsocket, il socket del chiamante dovrebbe scadere durante il successivo recv().


Non funziona per me; manca qualcosa. Forse s.listen(5)prima s.accept()?
bmaupin,

@bmaupin Sembra ragionevole, immagino di averlo dimenticato. Modificato ora (comunque con una coda di backlog di 0), grazie!
Henrik Heimbuerger,

1
Sono stato in grado di mettere l'ascolto e accettare le parti in un while True:ciclo, e questo sembra rendere una destinazione di timeout duratura piacevole da colpire per i test.
AlanSE,

2
Funziona, ma dà l'errore "read timeout", che non è lo stesso di "timeout della connessione"
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

Tutti questi non sono instradabili.


2
(Come ho commentato la risposta accettata) Quando ho testato un XMLHttpRequest in Node.js, le connessioni 10.0.0.0e hanno 10.255.255.255generato un errore EACCES anziché il timeout. 10.255.255.1, 172.16.0.0, 172.31.255.255, 192.168.0.0, E 192.168.255.255ha fatto il timeout, però.
Jamie Birch,

9

Vorrei rivolgere l'attenzione di tutti al patato

Con una configurazione (presa dai loro esempi) 200:b@100:drotterrai una connessione che cade casualmente.


1
Non uguale a un timeout
dentarg

8

Che ne dici di una soluzione software:

Installa il server SSH sul server delle applicazioni. Quindi, utilizzare il tunnel socket per creare un collegamento tra la porta locale e la porta remota sul server delle applicazioni. È possibile utilizzare gli strumenti client ssh per farlo. Invece, l'applicazione client si connette alla porta locale mappata. Quindi, è possibile interrompere il tunnel socket a piacimento per simulare il timeout della connessione.


4

Se si desidera utilizzare una connessione attiva, è anche possibile utilizzare http://httpbin.org/delay/# , dove # è il tempo che il loro server deve attendere prima di inviare una risposta. Finché il timeout è più breve del ritardo ... dovrebbe simulare l'effetto. L'ho usato con successo con il pacchetto di richieste python.

Potresti voler modificare la tua richiesta se stai inviando qualcosa di sensibile - non hai idea di cosa succede ai dati inviati.


Max 10 secondi però (se si inserisce un numero più alto risponderà dopo 10 secondi)
Harry Wood,

2

Sono disponibili servizi che consentono di creare artificialmente timeout di origine chiamando un'API in cui si specifica il tempo necessario per la risposta del server. Il timeout del server su macgyver è un esempio di tale servizio.

Ad esempio, se si desidera testare una richiesta che richiede 15 secondi per rispondere, è sufficiente inviare una richiesta post all'API macgyver.

Payload JSON:

{
    "timeout_length": 15000
}

Risposta API (dopo 15 secondi):

{
    "response": "ok"
}

Programma Timeout server su macgyver
https://askmacgyver.com/explore/program/server-timeout/3U4s6g6u


1

È possibile installare il driver Microsoft Loopback che creerà un'interfaccia separata per te. Quindi puoi collegarti ad esso per alcuni dei tuoi servizi (il tuo host). Quindi in Connessioni di rete è possibile disabilitare / abilitare tale interfaccia ...


1

Nonostante non sia del tutto chiaro quale OP vuole testare: c'è una differenza tra il tentativo di connessione a un host / porta inesistente e un timeout di una connessione già stabilita. Vorrei andare con Rob e aspettare fino a quando la connessione funziona e quindi tirare il cavo. Oppure, per comodità, disporre di una macchina virtuale che funzioni come server di test (con collegamento in rete) e che semplicemente disattivi l'interfaccia di rete virtuale una volta stabilita la connessione.


1

La tecnica che utilizzo frequentemente per simulare un timeout di connessione casuale consiste nell'utilizzare il port forwarding locale ssh.

ssh -L 12345:realserver.com:80 localhost

Questo inoltrerà il traffico su localhost: 12345 a realserver.com:80 Puoi eseguire il loop anche nel tuo computer locale, se vuoi:

ssh -L 12345:localhost:8080 localhost

Quindi puoi puntare la tua applicazione sul localhost e sulla porta personalizzata e il traffico verrà indirizzato all'host di destinazione: porta. Quindi puoi uscire da questa shell (potrebbe anche essere necessario ctrl + c la shell dopo essere uscito) e ucciderà l'inoltro che causa la perdita della connessione dell'app.


0

Collegare il cavo di rete a uno switch che non ha altri collegamenti / cavi. Dovrebbe funzionare imho.


0

Ci sono un paio di tattiche che ho usato in passato per simulare problemi di rete;

  1. Estrarre il cavo di rete
  2. Spegnere l'interruttore (idealmente con l'interruttore a cui è collegato il computer ancora alimentato in modo che la macchina mantenga la sua "connessione di rete") tra la macchina e la macchina "target"
  3. Esegui il software firewall sul computer di destinazione che elimina automaticamente i dati ricevuti

Una di queste idee potrebbe darti alcuni mezzi per generare artificialmente lo scenario di cui hai bisogno


0

A seconda del software firewall installato / disponibile, dovresti essere in grado di bloccare la porta in uscita e, a seconda di come è installato il tuo firewall, dovrebbe semplicemente rilasciare il pacchetto di richiesta di connessione. Nessuna richiesta di connessione, nessuna connessione, ne deriva un timeout. Questo probabilmente funzionerebbe meglio se fosse implementato a livello di router (tendono a rilasciare i pacchetti invece di inviare i reset, o qualunque sia l'equivalente per la situazione) ma c'è sicuramente un pacchetto software che farebbe anche il trucco.


0

La cosa più semplice sarebbe abbandonare la connessione usando CurrPorts .

Tuttavia, per testare l'unità del tuo codice di gestione delle eccezioni, forse dovresti prendere in considerazione l'idea di astrarre il tuo codice di connessione di rete e scrivere uno stub, un mock o un decoratore che genera eccezioni su richiesta. Sarai quindi in grado di testare la logica di gestione degli errori dell'applicazione senza dover effettivamente utilizzare la rete.


Con CurrPorts, sembra che sia solo in grado di chiudere la connessione (il che provoca recv()immediatamente il fallimento del successivo ), ma non sono riuscito a trovare un modo per simulare un timeout (ovvero non vengono trasferiti più dati, ma la connessione rimane aperta).
Henrik Heimbuerger,

Ho apprezzato questa risposta per aver suggerito un test unitario che deride le eccezioni di connessione su richiesta.
Danny Bullis,

0

Ho avuto problemi sulla stessa linea di te. Per testare il comportamento del software, ho appena scollegato il cavo di rete al momento opportuno. Ho dovuto impostare un punto di interruzione proprio prima di voler scollegare il cavo.

Se lo facessi di nuovo, inserirei un interruttore (un pulsante momentaneo normalmente chiuso) in un cavo di rete.

Se la disconnessione fisica provoca un comportamento diverso, è possibile connettere il computer a un hub economico e inserire lo switch sopra menzionato tra l'hub e la rete principale.

- MODIFICA - In molti casi è necessario che la connessione di rete funzioni fino a quando non si arriva a un determinato punto del programma, ALLORA si vorrà disconnettersi utilizzando uno dei tanti suggerimenti offerti.


0

Per me il modo più semplice era l'aggiunta di route statiche sul router dell'ufficio in base alla rete di destinazione. Instrada il traffico verso un host che non risponde (ad es. Il tuo computer) e otterrai il timeout della richiesta.

La cosa migliore per me è che il percorso statico può essere gestito tramite l'interfaccia web e abilitato / disabilitato facilmente.


-1

Puoi provare a connetterti a uno di siti Web noti su una porta che potrebbe non essere disponibile dall'esterno, ad esempio 200. La maggior parte dei firewall funziona in modalità DROP e simulerà un timeout per te.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.