Штучно створити помилку тайм-ауту з'єднання


291

У нас виникло помилка в нашому програмному забезпеченні, яка виникає, коли я отримую час очікування на з'єднання. Ці помилки трапляються дуже рідко (як правило, коли моя внутрішня мережа потрапляє у зв’язок). Як я можу створити подібний ефект штучним шляхом, щоб я міг протестувати наше програмне забезпечення?

Якщо це важливо, додаток пишеться на C ++ / MFC за допомогою класів CAsyncSocket.

Редагувати:

Я намагався використовувати неіснуючий хост, і я отримую помилку сокета:

WSAEINVAL (10022) Неправильний аргумент

Наступною моєю спробою було використання пропозиції Олександра щодо підключення до іншого порту, наприклад 81 (хоча на власному сервері). Це працювало чудово. Точно так само, як і перерване з'єднання (60 секунд очікування, потім помилка). Дякую!


Привіт Марку, я спробував рішення, яке працює для вас, але те, що я отримую, - це # 503 (Служба недоступна.). Чи не повинно бути одним із них, №504 (час очікування шлюзу), # 599 (помилка очікування підключення до мережі), # 598 (помилка очікування мережевого зчитування).
CoDe

Відповіді:


297

Підключіться до існуючого хосту, але до порту, який блокується брандмауером, який просто скидає пакети TCP SYN. Наприклад, www.google.com:81.


6
Ця відповідь проста і працює так само, як відповідь @ emu нижче. Я розумію, що ця відповідь не збирається пропонувати використовувати google.com:81, але справа в тому, щоб використовувати інший порт, який заблокований. Таким чином, ви завжди можете використовувати <your-own-ip>: <blocked-port>.
Джеймс Сельвакумар

6
Якщо це не ваш власний сервер, його грубість потрапляє на інші сервери для тестування. Скористайтеся цивілізованим рішенням, таким як вказане нижче в ему, натиснувши IP-адресу без маршрутизації, наприклад 10.255.255.1, або встановіть власний віртуальний сервер для тестування.
Зеешан

2
Я думаю, що Google, можливо, заблокував цей порт. Коли я тестую це за допомогою Chrome, я просто "Сервер недоступний". Коли я використовую хитрість @ emu нижче, з'єднання висить, як очікувалося. Я щось пропускаю?
entpnerd

ОП каже, що він підключився до порту 81 на власному сервері та отримав тайм-аут. Це працювало і для мене. Рішення ему дало мені UnknownHostException на Android.
Barry Fruitman

2
Це дасть з'єднання, відхилене не таймаутом.
Мехді

425

Підключіться до IP-адреси без маршрутизації, наприклад 10.255.255.1.


12
Idem, і я думаю, це краща відповідь, оскільки google.com:81 може бути доступний одного дня.
Gui13

138
... і тому, що надсилання випадкових пакетів на чужі сервери з ваших тестових пристроїв є грубим.
Гленн Мейнард

15
Це не завжди спрацює. Наприклад, з Python urllib, це поверне виняток "Нема маршруту до хоста". FYI
Майк Шульц

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, все це неперекладається.
rajesh_kw

4
Помилка "Немає маршруту до хосту", згадана @FHI, як правило, з'являється в двох умовах: (а) при спробі підключення до недоступного хоста у вашій локальній локальній мережі (це означає, що він не відповідає на запити ARP, тому це в основному " Час очікування ARP "). І (b) коли маршрутизатор повертає відповідну помилку ICMP. Перший випадок трапляється, якщо ви перебуваєте в тій самій підмережі, що і тестування приватного IP. Другий випадок, якщо маршрутизатор не знає, як направити ваш пакет до місця призначення, але в деяких випадках вони просто скидають пакет, не надсилаючи помилку ICMP.
Але

47

Якщо ви працюєте на Unix-машині, ви можете запустити прослуховування портів за допомогою netcat:

nc -l 8099

Потім змініть службу, щоб викликати все, що вона зазвичай робить, до цього порту, наприклад http: // localhost: 8099 / some / sort / of / endpoint

Тоді ваша служба відкриє з'єднання та записувати дані, але ніколи не отримає відповіді, і таким чином дасть вам час очікування читання (замість того, щоб з'єднання відмовлено)


1
Це корисно, оскільки ви можете бачити будь-які дані, які натискає ваша програма. Ви можете перевірити, чи запитує ваша заявка відповіді.
Поль

Це справедливо для навігації до якоїсь кінцевої точки, як згадувалося, але якщо я спробую з'єднати іншим способом, це швидко дає з'єднання відмовлено, що не є поведінкою, над якою я намагаюся зараз знущатися.
AlanSE

@AlanSE - про який інший спосіб ви маєте на увазі? Ви можете мати що завгодно після номера порту; netcat не піклується, оскільки у нього немає нічого, щоб обробити будь-які URL-адреси
Том Чемберлен

@TomChamberlain О, зачекайте, я можу знати, що я робив не так. Я намагаюся імітувати тайм-аут з'єднання ssh. Тож я даю йому localhost, порт 8099, але раніше я не давав імені користувача, тому якщо я просто щось вклав ssh alanse@localhost -p 8099, схоже, що це робить.
AlanSE

7
Щоб перевірити час очікування з'єднання на рівні сокета, заморозьте процес nc за допомогою kill -STOP <pid>(або просто CTRL-Z його, не ставлячи у фоновий режим). Система буде діяти так, ніби сервер працює, але зачекайте, коли сервер прийме з'єднання, що призведе до тайм-ауту з'єднання (errno 110).
благодійник

27

Наступна URL-адреса завжди дає час та поєднує найкращі відповіді @Alexander та @ Emu вище:

http://example.com:81

Використання example.com:81- це вдосконалення відповіді Олександра, оскільки example.com зарезервований стандартом DNS, тому він завжди буде недоступним, на відміну від цього google.com:81, яке може змінитися, якщо Google відчує, що це подобається. Крім того, оскільки example.comце визначено як недоступне, ви не затопите сервери Google.

Я б сказав, що це поліпшення порівняно з відповіддю @ emu, тому що це запам'ятати набагато простіше.


2
В даний час я бачу example.comдозвіл до 93.184.216.34, і фактично подає короткий HTML, пояснюючи це прикладом домену ... порт 81 все ще не відповідає.
Бені Чернявський-Паскін

Питання справді, чи передбачається, що example.com використовується таким чином. Тільки якщо вони дозволяють офіційно вільно заливатися тестовими пакетами, цей домен краще, ніж будь-який інший комерційний домен. Використання доменів для такої мети без дозволу не менш неетично, якщо не незаконно, тому що обробляти ці пакети коштує комусь грошей. Подумайте про використання, httpstat.usяк @AndyTheEntity вказав у своїй відповіді.
Мануель

@Manuel Вам не вистачає суті ... example.comце не комерційний домен, це одне з небагатьох імен домену, яке прямо вказано як непридатне для використання. Ніхто не може володіти, example.comа маршрутизатори DNS не знають, що він ніколи не спрямовується до реальної адреси. Тож це не коштує нікому серверного часу, немає нічого поганого в його використанні
speedplane

@speedplane IANA належить домену за допомогою регулювання та підтримує веб-сервер, який надає веб-сторінку, що пояснює мету example.com. За домену стоїть інфраструктура, тому кожен запит коштує грошей IANA. Дозволене використання посилається на RFC 2606 та RFC 6761, ви не вільні використовувати домени з будь-якою метою, як вам floddingзамість іншого сервера, як ви вже згадували. Ваша претензія, яка example.com is defined to be unreachableє неправильною, вона доступна. Порт 81 зараз недоступний, але де це визначено для гарантування в майбутньому?
Мануель

RFC, на який ви вказуєте, спеціально дозволяє проводити тестування DNS. Вони рекомендують .testскоріше використовувати домен верхнього рівня example.com, але ці домени були чітко налаштовані для цієї мети. Так, це може коштувати IANA трохи грошей, але це послуга, яку вони надають. Наші збори DNS платять за це.
швидкісний літак

23

Дуже багато відповідей, але найчистішим рішенням здається ця послуга

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

Ви можете налаштувати тривалість часу очікування (до 230 секунд) та можливий код повернення.


16

Ви можете використовувати Python REPL для імітації тайм-ауту під час отримання даних (тобто після успішного встановлення з'єднання). Не потрібно нічого, крім стандартної установки 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()

Тепер він чекає вхідного з'єднання. Підключіть те, що ви хочете перевірити localhost:9000. Коли ви зробите це, Python прийме з'єднання і accept()поверне його. Якщо ви не надсилаєте будь-які дані через clientsocket, розетка абонента повинна вичерпатися протягом наступного recv().


Не працює для мене; чогось не вистачає. Можливо, s.listen(5)раніше s.accept()?
bmaupin

@bmaupin Це звучить розумно, я думаю, я просто забув це. Відредагував його зараз (проте, з чергою відставання 0), дякую!
Генрік Хаймбургер

1
Мені вдалося поставити прослуховування та прийняття деталей у while True:циклі, і це, здається, зробило приємне довговічне місце очікування на тестування.
AlanSE

2
Він працює, але він дає помилку «таймаут», який не є таким же , як «Час очікування з'єднання»
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

Все це є непровідними.


2
(Як я прокоментував прийняту відповідь) Коли я тестував XMLHttpRequest в Node.js, підключення до 10.0.0.0та 10.255.255.255запущено помилку EACCES, а не вичерпання часу. 10.255.255.1, 172.16.0.0, 172.31.255.255, 192.168.0.0, І 192.168.255.255зробив тайм - аут, однако.
Джеймі Береза

9

Я хотів би всіх звернути увагу на шлях

За допомогою конфігурації (взятої з їх прикладів) 200:b@100:drви отримаєте з'єднання, яке випадково перестає.


1
Не такий, як тайм-аут
dentarg

8

Як щодо програмного рішення:

Встановіть SSH-сервер на сервер додатків. Потім скористайтеся тунелем розетки, щоб створити зв’язок між вашим локальним портом та віддаленим портом на сервері додатків. Для цього можна використовувати клієнтські інструменти ssh. Запропонуйте клієнтській програмі підключитися до вашого картографічного локального порту. Потім ви можете розірвати тунель розетки за бажанням, щоб імітувати час очікування з'єднання.


4

Якщо ви хочете використовувати активне з'єднання, ви також можете скористатися http://httpbin.org/delay/# , де # - час, коли потрібно, щоб сервер чекав, перш ніж надсилати відповідь. Поки ваш тайм-аут коротший затримки ... повинен імітувати ефект. Я успішно використовував його з пакетом запитів python.

Ви можете змінити свій запит, якщо ви надсилаєте що-небудь чутливе - не маєте уявлення, що відбувається з надісланими їм даними.


Максимум 10 секунд (якщо ви введете більшу кількість, він відповість через 10 секунд)
Гаррі Вуд

2

Доступні сервіси, які дозволяють вам штучно створювати тайм-аути вихідного сигналу, зателефонувавши в API, де ви вкажете, скільки часу серверу потрібно буде відповісти. Тайм-аут сервера в macgyver - приклад такої послуги.

Наприклад, якщо ви хочете перевірити запит, на який потрібно відповісти 15 секунд, ви просто зробите поштовий запит до API macgyver.

Корисна навантаження JSON:

{
    "timeout_length": 15000
}

Відповідь API (через 15 секунд):

{
    "response": "ok"
}

Програма очікування сервера на macgyver
https://askmacgyver.com/explore/program/server-timeout/3U4s6g6u


1

Ви можете встановити драйвер Microsoft Loopback, який створить для вас окремий інтерфейс. Потім ви можете підключити його до якогось вашого сервісу (власного хоста). Потім у мережевих підключеннях ви можете відключити / включити такий інтерфейс ...


1

Незважаючи на те, що не зовсім зрозуміло, який саме ОП хоче перевірити: є різниця між спробою підключення до неіснуючого хоста / порту та таймаутом вже встановленого з'єднання. Я б пішов з Робом і зачекав, поки з'єднання запрацює, а потім потягну кабель. Або - для зручності - мати віртуальну машину, яка працює в якості тестового сервера (з мостовою мережею) і просто деактивує віртуальний мережевий інтерфейс після встановлення з'єднання.


1

Метод, який я часто використовую для імітації випадкового тайм-ауту з'єднання, полягає у використанні ssh-локального переадресації портів.

ssh -L 12345:realserver.com:80 localhost

Це переадресує трафік на localhost: 12345 на realserver.com:80 Ви також можете зафіксувати це на власній локальній машині, якщо хочете:

ssh -L 12345:localhost:8080 localhost

Таким чином, ви можете направити свою програму на ваш локальний та власний порт, і трафік буде спрямований на цільовий хост: порт. Тоді ви можете вийти з цієї оболонки (можливо, вам також знадобиться ctrl + c оболонку після виходу), і це знищить переадресацію, через що ваш додаток побачить втрату з'єднання.


0

Підключіть мережевий кабель до комутатора, який не має інших підключень / кабелів. Це повинно працювати.


0

Існує кілька тактик, які я використовував у минулому для моделювання проблем у мережі;

  1. Витягніть мережевий кабель
  2. Вимкніть перемикач (в ідеалі за допомогою перемикача, на якому комп'ютер підключений до живлення, щоб машина підтримувала його "мережеве з'єднання") між вашою машиною та "цільовою" машиною
  3. Запустіть програмне забезпечення брандмауера на цільовій машині, яке мовчки скидає отримані дані

Одна з цих ідей може дати вам певні засоби штучного створення необхідного сценарію


0

Залежно від того, яке програмне забезпечення брандмауера встановлено / доступно, ви повинні мати можливість блокувати вихідний порт, і залежно від налаштування вашого брандмауера, він повинен просто скинути пакет запиту на з'єднання. Ні запиту на з'єднання, ні підключення, не настає час очікування. Це, мабуть, буде краще, якби він був реалізований на рівні маршрутизатора (вони, як правило, скидають пакети замість того, щоб відправляти скидання, або все, що еквівалентно для ситуації), але там, мабуть, є програмний пакет, який теж би трюк.


0

Найпростіше було б перервати своє з'єднання за допомогою CurrPorts .

Однак, щоб перевірити свій код обробки винятків, можливо, вам слід розглянути можливість зменшення коду підключення до мережі та написати заглушку, макет чи декоратор, який викидає винятки на вимогу. Після цього ви зможете перевірити логіку керування помилками програми, не використовуючи мережу.


З CurrPorts, здається, я зможу лише закрити з'єднання (що призводить recv()до негайного наступного наступного ), але не вдалося знайти спосіб імітувати тайм-аут (тобто більше даних не передається, але з'єднання залишається відкритим).
Генрік Хаймбургер

Я високо оцінив цю відповідь за те, що запропонував тестовий пристрій, який висміює виключення підключення на вимогу.
Денні Булліс

0

У мене виникли проблеми, як і у вас. Щоб перевірити поведінку програмного забезпечення, я просто відключив мережевий кабель у відповідний час. Мені довелося встановити точку розриву прямо перед тим, як захотіти відключити кабель.

Якби я робив це знову, я поставив би перемикач (звичайно закритий моментний натискання кнопки) в мережевий кабель.

Якщо фізичне відключення викликає іншу поведінку, ви можете підключити комп'ютер до дешевого концентратора і поставити перемикач, про який я згадував вище, між вашим концентратором і основною мережею.

- РЕДАКТУВАННЯ - У багатьох випадках вам потрібно буде працювати мережеве з'єднання до тих пір, поки ви не дістанетесь до певної точки вашої програми, ТОГО вам захочеться відключитись за допомогою однієї з багатьох запропонованих пропозицій.


0

Для мене найпростішим способом було додавання статичного маршруту на маршрутизатор офісу на основі мережі призначення. Просто спрямовуйте трафік на якийсь невідповідний хост (наприклад, ваш комп'ютер), і ви отримаєте тайм-аут запиту.

Найкраще для мене було те, що статичним маршрутом можна керувати через веб-інтерфейс та легко вмикати / відключати.


-1

Ви можете спробувати підключитися до одного з відомих веб-сайтів на порту, який може бути недоступний зовні - наприклад, 200. Більшість брандмауерів працюють у режимі DROP, і це буде імітувати час очікування.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.