開こうとしているポートを転送した後、そのポートに接続できないか、ポートからデータを取得できないようです。私が書いたPHP CLIソフトウェアは、ポートで積極的にリッスンしています。Ubuntu14.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も表示され、正常に機能し、外部ポートの確認Webサイト(ポート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を使用すると、ポートも開いているように見えます。私も別のポートを試しました。私のクライアント接続スクリプトは、WindowsでPHP CLIを実行したときに接続するJavaScript Webソケットスクリプトです。スクリプトが長すぎるため、ここに含めることができず、外部ネットワークから接続できません。 JSおよびPHPスクリプトをローカルアドレス127.0.0.1または192.168.0.###に設定すると機能しますが、LAN外部デバイスでは機能しません。
// 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');
iptables以外にバイパスしないLinuxに欠けているファイアウォールはありますか? ApacheはPCの他のソフトウェアと同様にポートを正しく開きますが、私のスクリプトには外部使用のためにポートを完全に開くために必要な手順がありません。
TL、PhD。 JavaScriptクライアントを使用して外部IPアドレスを使用して、Ubuntu以外のWindowsで実行されているPHPサーバーに接続します。ポート転送、監視、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日間再起動せずに速度がかなり遅くなり、あまりにも多くの変更をしたくありません。
これファームウェアの更新によりポート転送ページが変更されました外部リモートホストアドレス部分(デフォルトは0.0.0.0)を含めることはここでは問題ではありませんが、私が設定した既存のポート転送ルールに違反します。
転送できないポート範囲を使用しましたが、この範囲を8399 - 8399に変更すると再び機能し始めました。モデムの高速化に加えて、再起動しても何の影響もなく、プロトコルを両方から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
また、LinuxでPHPコマンドgethostbyname(gethostname())を使用すると、返されるアドレスは/ etc / hostsファイルの2番目のエントリであるローカルアドレス127.0.1.1です。これはバインドされたソケットには適用されません。 $_SERVER['REMOTE_ADDR'] も次の警告を返します。ホストが見つかりません。渡す自宅(サブネット?)アドレス(私のアドレスは192.168.0.101)またはIPv4ワイルドカード0.0.0.0に手動で変更してください。、ソケットレシーバーが正しくバインドされ、外部接続を許可します。
ルーターの経験とLinuxの経験の欠如は、Linuxのトラブルシューティングにおいて間違った方法で落ちる傾向がありました。 Windows 7でも問題が正しく機能しないことを確認した後、上記の2つの点を変更し、すべてがうまく機能します。