Проверьте, закрыт ли сокет в bash? - PullRequest
6 голосов
/ 06 июля 2011

У меня есть дескриптор файла, который указывает на сокет (пример кода ниже).

exec 3<>/dev/tcp/localhost/9999
echo -e "Some Command\n" >&3

Иногда этот сокет закрывается и его необходимо открыть заново (перезапуск сервера).

Как я могу проверить, доступен ли для записи сокет (в данном случае fd # 3)?

Эхо всегда будет успешным независимо от того, был ли сокет уже закрыт или нет.

Ответы [ 5 ]

4 голосов
/ 06 июля 2011

Решение - это обратная связь с сервером.

Когда вы отправляете запрос на сервер, он должен ответить на него.

exec 3<>/dev/tcp/localhost/9999
echo -e "Some Command\n" >&3
sleep 5 # example max time given to server to respond
cat <&3 #receive an answer
check is correct, restart server otherwise

EDIT: используя netcat, чтобы определить, открыт ли порт

netcat -w 3 -z www.google.com 80
if[ $? -eq 0 ]
then
    echo port open
else
    echo port closed
fi
3 голосов
/ 09 марта 2012

Прошло некоторое время с тех пор, как оп опубликовал это, поэтому они могут не видеть этого, но это может помочь кому-то еще.

В любом случае, я изучал эту проблему и обнаружил следующее.

Открытые fd (файловые дескрипторы) процесса перечислены в /proc//fd.

exec 3<>/dev/tcp/localhost/9999

#check if still connected
if [ $(ls /proc/$$/fd | grep -w "3") == 3 ]; then
  #send data 
  echo -e "Some Command\n" >&3  
else
  #perform reconnect
  exec 3<>/dev/tcp/localhost/9999
fi

Это не было проверено, но должно быть в основном нормально.Могут быть и некоторые улучшения.Также есть окно, где fd исчезает между вашей проверкой и записью в fd.Однако это касается всех решений.

1 голос
/ 07 июля 2011

Я добавлю свое собственное окончательное решение (в кратком псевдокоде):

{ while true; 
  read file; 
  write to STDOUT } | 
{ while true; 
  netcat command; 
  write STDIN to buffer when/if netcat exits; 
  loop to restart netcat & first process buffered data if exists; }

Это разделяет вывод данных (чтение файла) и обработку данных (отправка их в сокет или буферизация в файл, когда сокет недоступен). Он использует канал для предоставления временного буфера при возникновении проблем с сетью.

STDIN второго кодового блока буферизует вывод из первого кодового блока. Если netcat не может обработать данные на stdin, он выберет запись в буферный файл и попытается перезапустить netcat. Таким образом, у вас не будет никакого промежутка времени между проверкой того, что сокет открыт (что все еще сложно), и фактической записью (которая может все же завершиться ошибкой после проверки, что она открыта).

0 голосов
/ 06 июля 2011

Попробуйте написать на фд:

if ! echo some text >&3;
  then echo The port is closed >&2
fi

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

0 голосов
/ 06 июля 2011

Вы можете использовать команду netstat, grep для нужного порта / адреса, а затем cut только для поля состояния. Обратите внимание, что сокет может отображаться как «УСТАНОВЛЕННЫЙ» в течение некоторого времени после потери соединения, особенно если вы не отправляете на него какие-либо данные.

...