2013-04-08 4 views
4

Я написал веб-сервер, скажем, пакет веб-сервера, и может запустить его в GHCI с:Как завершить работу сокета-сервера в ghci?

:main localhost 8000 

Если я Ctrl-C его и запустить это снова, я получаю

*** Exception: bind: resource busy (Address already in use) 

Итак, сокет, похоже, связан с моей сессией ghci.

Как я могу освободить этот привязку порта, чтобы я мог :reload и запустить его снова, не покидая ghci?

ответ

0

Вы в Linux? Если да, я думаю, что вам нужно использовать lsof, чтобы узнать, какой процесс использует данный порт, а затем просто убить PID. У меня уже была проблема с Flask на Python, поэтому я думаю, что здесь одно и то же. Вы оставляете ghci открытым, убиваете процесс, а затем перезагружаете ghci. Это не элегантный метод, но если он работает, это хорошо!

+0

Приятная идея, но это убивает мой весь ghci. – nh2

3

Это обычно происходит, если реализация базового сервера не устанавливает параметр REUSE_ADDR в сокете.

Обычно, если вы прекратите работу сервера внезапно, операционная система сохраняет старый сервер этого сервера в состоянии 2MSL в течение нескольких минут, чтобы предотвратить появление новых серверов на этом порте от случайного приема старых сообщений, предназначенных для предыдущего соединения. Если вы установили REUSE_ADDR при попытке привязки порта, вы указываете, что хотите повторно использовать его до истечения периода 2MSL.

Единственный способ исправить это - изменить код базового веб-сервера, который вы используете, чтобы установить опцию REUSE_ADDR перед привязкой прослушивающего сокета.

+0

Я не извращаю 'REUSE_ADDR' - проблема - сокет сразу становится свободным после того, как я ушел из ghci. Моя проблема в том, что мне нужно, чтобы это произошло на 'Ctrl-C', который завершает main. – nh2

+0

@ nh2 В этом случае я не уверен. Я думал, что ': reload' будет способом сбросить' ghci' и освободить все ресурсы, но вы уже сказали, что это не работает. –

+2

'ghci' не знает, что сокет даже открыт. Вашему серверу нужно будет ловить сигналы, поймать 'SIGINT' (среди прочих) и закрыть сокет, когда он получит этот сигнал. И да, вам все равно потребуется опция «REUSE_ADDR», хотя звучит так, как будто она установлена. – MtnViewMark

Смежные вопросы