Привязка к порту с помощью netpipes / netcat - PullRequest
3 голосов
/ 08 января 2011

Я пытаюсь написать простой bash-скрипт, который прослушивает порт и отвечает тривиальным HTTP-ответом. Моя конкретная проблема заключается в том, что я не уверен, доступен ли порт, и в случае сбоя связывания я возвращаюсь к следующему порту, пока связывание не будет успешным.

До сих пор для меня самый простой способ достичь этого был что-то вроде:

for (( i=$PORT_BASE; i < $(($PORT_BASE+$PORT_RANGE)); i++ ))
do
  if [ $DEBUG -eq 1 ] ; then
    echo trying to bind on $i
  fi
  /usr/bin/faucet $i --out --daemon echo test 2>/dev/null
  if [ $? -eq 0 ] ; then                        #success?
    port=$i
    if [ $DEBUG -eq 1 ] ; then
      echo "bound on port $port"
    fi
    break
  fi
done

Здесь я использую faucet из netpipes Пакет Ubuntu.

Проблема в том, что если я просто напечатаю «test» на выходе, curl жалуется на нестандартный HTTP-ответ (код ошибки 18). Это достаточно справедливо, поскольку я не печатаю HTTP-совместимый ответ.

Если я заменю echo test на echo -ne "HTTP/1.0 200 OK\r\n\r\ntest", curl по-прежнему жалуется:

user@server:$ faucet 10020 --out --daemon echo -ne "HTTP/1.0 200 OK\r\n\r\ntest"
...
user@client:$ curl ip.of.the.server:10020
curl: (56) Failure when receiving data from the peer

Я думаю, что проблема заключается в том, как faucet печатает ответ и обрабатывает соединение. Например, если я делаю на стороне сервера в netcat, curl работает нормально:

user@server:$ echo -ne "HTTP/1.0 200 OK\r\n\r\ntest\r\n" | nc -l 10020
...
user@client:$ curl ip.of.the.server:10020
test
user@client:$

Я был бы более чем рад заменить faucet на netcat в моем основном скрипте, но проблема в том, что я хочу порождать процесс независимого сервера, чтобы иметь возможность запускать клиент из той же базовой оболочки. У faucet есть очень удобный параметр --daemon, так как он разветвляется на фон, и я могу использовать $? (код состояния выхода), чтобы проверить, удалось ли связывание. Если бы я использовал netcat для аналогичной цели, мне пришлось бы раскошелиться, используя &, и $? не сработало бы.

Кто-нибудь знает, почему faucet не отвечает правильно в данном конкретном случае и / или может предложить решение этой проблемы. Я не женат ни на faucet, ни netcat, но хотел бы, чтобы решение было реализовано с использованием bash или его утилит (в отличие от написания чего-либо на еще одном языке сценариев, таком как Perl или Python).

Ответы [ 4 ]

4 голосов
/ 08 января 2011
faucet 10020 --out --daemon \
    echo -ne "HTTP/1.0 200 OK\r\nContent-Length: 4\r\n\r\ntest"

отлично работает. Кажется, проблема в том, что echo не знает, как правильно shutdown сокет, используя вместо этого просто close, а curl недоволен получением -1 (случайное отключение) вместо 0 (обычное выключение) с recvfrom.

Попробуй socat, который остается, чтобы вымыться после того, как ребенок закончил.

socat tcp-l:10020,fork,reuseaddr \
    exec:'echo -ne "HTTP/1.0 200 OK\r\n\r\ntest"'
2 голосов
/ 09 января 2011

Может быть, взгляните и на программу "носка" Ричарда Стивенса.Он имеет:

-F    fork after connection accepted   (TCP concurrent server)

http://www.icir.org/christian/sock.html

. Используя Bash, вы также можете использовать:

echo $'HTTP/1.0 200 OK\r\n\r\ntest\r\n'
1 голос
/ 08 января 2011

Как насчет использования программы tcpserver из пакета DJB ucspi-tcp.

http://lserinol.blogspot.com/2008/12/simple-tcp-server-with-djb-tcpserver.html

Продвинутой альтернативой netcat или nc соответственно является ncat (часть nmap).

1 голос
/ 08 января 2011

вам действительно нужно использовать протокол HTTP или это просто для удовольствия?если это последнее, просто объедините

 faucet $port --out --daemon echo test

с

 hose $server $port --in cat
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...