Как мне получить доступ к открытому и прослушиваемому порту в Linux?

Как мне получить доступ к открытому и прослушиваемому порту в Linux?

После переадресации порта, который я хочу открыть, я не могу подключиться или получить какие-либо данные на этот порт. Программное обеспечение PHP CLI, которое я написал, активно прослушивает порт наУбунту 14.04. Часть кода показана ниже. Порт открыт как AF_INET, скрипт не выдает ошибок для каждой строки, а в /etc/protocols tcp определен как 'tcp 6 TCP'.

// I have tried $host=gethostbyname(gethostname());$port=8399 (host is 127.0.1.1)
// as well as $host = '0.0.0.0'; $port = 8399; and other addresses

$this->wsRead[0] = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)
socket_set_option($this->wsRead[0], SOL_SOCKET, SO_REUSEADDR, 1)
socket_bind($this->wsRead[0], $host, $port) 
socket_listen($this->wsRead[0], 10)
while (isset($this->wsRead[0])) { /* Handshake/Process data, etc. */ }

Порты переадресованы и мойiptables пусты, хотя я пробовал специально добавлять разрешающее правило для порта. Я пробовал запускать скрипт как суперпользователь. Когда сервер слушает, netstat -tuln выводит эту строку (с моим портом 8399), и я замечаю, что apache также выводится, что работает нормально и отображается как открытый порт на внешних сайтах проверки портов (на порту 8301):

Proto Recv-Q Send-Q Local Address      Foreign Address    State
tcp        0      0 0.0.0.0:8399       0.0.0.0:*          LISTEN
tcp6       0      0 :::8301            :::*               LISTEN
tcp6       0      0 :::80              :::*               LISTEN

Используя nmap, порт также показывает, что он открыт. Я также пробовал разные порты. Мой клиентский скрипт подключения — это скрипт JavaScript websocket, который работает для подключения при запуске PHP CLI в Windows. Скрипт слишком длинный, чтобы включать его здесь, и он не подключается из внешней сети. Если я устанавливаю оба скрипта JS и PHP на локальные адреса 127.0.0.1 или 192.168.0.###, то он работает, но не с устройства за пределами моей локальной сети.

// The JS is basically this, plus some connection events to alert success/fail.
// This external connection request will always time out
Server = new WebSocket('ws://68.215.154.129:8399');

Может, мне не хватает какого-то брандмауэра в Linux, кроме iptables, который я не обхожу? Apache правильно открывает порты и другое ПО на ПК, но, похоже, в моем скрипте отсутствует необходимый шаг для полного открытия порта для внешнего использования.

tl,dr; Подключение с использованием внешнего IP-адреса с помощью JavaScript-клиента к PHP-серверу, работающему в Windows, но не в Ubuntu.Порт перенаправлен, прослушивается, не блокируется iptables, то, что осталось?

решение1

Вы что-то упускаете концептуально и в коде. У вас есть PHP-код, который прослушивает соединения, но вы должны принять соединение перед его использованием.

$ns = socket_accept($this->wsRead[0]);
$some_string = socket_read($ns, 128);

Вызов socket_accept()блокирует. Он не вернется, пока какая-либо клиентская программа не подключится к программе, ожидающей соединения.

Вызов socket_accept()возвращает фактический сокет, который вы используете для связи с удаленной программой. Я не думаю, isset()что это действительно то, что вам нужно, вам следует изучить socket_select()или что-то в этом роде. Когда вы закончите общаться с удаленным, вы вызываете socket_close($ns), а затем возвращаетесь к вызову, socket_accept($this->wsRead[0])чтобы дождаться, пока другая удаленная программа подключится к вашей программе.

Когда ваша PHP-программа завершает обработку соединений, она должна вызвать socket_close($this->wsRead[0])функцию закрытия сокета, что по сути означает, что ядру ОС следует прекратить прослушивание входящих TCP SYN-пакетов для указанного вами порта.

решение2

Оказывается, проблема была в нескольких вещах, в основном из-за моего модема/маршрутизатора. Я используюМоторола SB6580, который недавно обновил прошивку и не перезагружался в течение 10 дней, из-за чего он стал работать довольно медленно и мне не хотелось вносить в него слишком много изменений.

Theобновление прошивки изменило страницу переадресации портоввключить раздел адреса внешнего удаленного хоста (по умолчанию 0.0.0.0) — тут проблем нет, но что-то еще, что они сделали, нарушило существующие правила переадресации портов, которые я установил.

Я использовал диапазон портов для переадресации, который не работал, и, изменив этот диапазон на 8399 - 8399, он снова заработал. Перезапуск не повлиял на него, кроме увеличения скорости модема, как и изменение протокола с Both на TCP.

IP Addr|Start Port|End Port|Remote Host Addr|Start Port|End Port|Protocol|Enabled
192.168.0.101|8340|    8399|         0.0.0.0|      8340|    8399|    Both|Checked
192.168.0.101|8399|    8399|         0.0.0.0|      8399|    8399|     TCP|Checked

Кроме того, при использовании команды PHP gethostbyname(gethostname()) в Linux возвращаемый адрес является локальным адресом 127.0.1.1, второй записью в файле /etc/hosts, которая не будет работать для привязки сокета. $_SERVER['REMOTE_ADDR'] также возвращает предупреждение: невозможно найти хост. Повручную изменить его на домашний адрес (подсети?) (мой 192.168.0.101) или подстановочный знак IPv4 0.0.0.0, прослушиватель сокетов привязан правильно и принимает внешние соединения.

Мой опыт работы с маршрутизатором и неопытность в Linux заставили меня склониться к неправильному пути устранения неполадок Linux. Заметив, что и в Windows 7 все не работает, я внес 2 изменения выше, и теперь все работает как надо.

Связанный контент