2

ポート8195で単純なリスナーを作成しようとしています。PHPCLI条件で次のコードブロックを試してみると、「Test」が1回だけ表示され、その後ハングします。オン/オフスイッチとして設計されたファイル「votifier.run」を削除しても、引き続きハングします。「クライアントが接続されています」と表示されることはありません。

さらに、スクリプトの実行中にポート8195でTelnet経由でホストに接続しようとすると、接続に失敗したというメッセージが表示されます。それは、1つの接続を探していて、あきらめないようなものです。

// Set the IP and port to listen to
$address = 'localhost';
$port = 8195;

// Create a TCP Stream socket
$sock = socket_create(AF_INET, SOCK_STREAM, 0);
// Bind the socket to an address/port
socket_bind($sock, $address, $port);
// Start listening for connections
socket_listen($sock);

// Loop continuously
while ( file_exists('votifier.run') ) {
    echo 'Test';
    $client = socket_accept($sock);
    if( $client ) {
            echo 'Client connected';
            // Don't hang on slow connections
            socket_set_timeout($client, 5);

            // Send them our version
            socket_write("VOTIFIER MCWEBLINK\n");

            // Read the 256 byte block
            $block = socket_read($client, 256);
            ...

答え: socket_accept()は通常、接続が確立されるまでハングします。接続が試行された場合、スクリプトは続行されますが、ソケットはローカルホストで作成されていたため、ローカルホストからの接続のみを受け入れます。

修正は、「localhost」または「127.0.0.1」ではなく外部IPを使用することです。次に、Telnetで接続できます。

4

3 に答える 3

3

ここで推測しているだけですが、バインドしようとしているアドレスがホスト名であってはならない可能性がありますか?

ソケットがAF_INETファミリの場合、アドレスはドットクワッド表記のIPです(例:127.0.0.1)。

編集

わかりました。スクリプトを取得してエラーを再現しようとしましたが、再現できませんでした。そこにはいくつかの欠陥がありますが、Telnetクライアントの接続の試みが失敗する原因となる欠陥はありません。

上記のいずれにも当てはまらないので、チェックリストを1つずつ見ていきましょう。

  • ロード/コンパイルされたソケットモジュール
  • ローカルホストは127.0.0.1に解決されます
  • ポートは、実行中の他のアプリケーションによって使用されません
  • telnetクライアントとサーバー間の通信を妨げるファイアウォールのルールはありません
  • 接続元のマシンはサーバーホストに接続できます(そうでない場合は同じホストを試してください)
  • whileループでチェックされているファイルは存在します
  • 投稿したスニペットの実行を妨げるような致命的なエラーがスクリプト内にないことを確認してください

これらは私が考えることができるすべての可能なエラーソースです、atm。最初に小さな欠陥を修正してから、チェックリストを確認してください。

if( $client ) {
    echo 'Client connected';
    // Don't hang on slow connections
    socket_set_option(
        $client,
        SOL_SOCKET,
        SO_RCVTIMEO | SO_SNDTIMEO,
        array('sec' => 5, 'usec' => 0)
    );

    // Send them our version
    socket_write($client, "VOTIFIER MCWEBLINK\n");
                 ^^^^^^^

    // Read the 256 byte block
    $block = socket_read($client, 256);
于 2012-08-14T08:16:57.363 に答える
0

スレッドを使用する必要があります。クライアントが何も送信しない場合、コードはread()メソッドでブロックされます。受け入れられた各ソケットは、新しいスレッドで完全に処理される必要があります。

于 2012-08-14T10:33:51.933 に答える
-1

これを確認することをお勧めします: MinecraftトップサイトのPHPVotifierの例

コードがどのように機能するかを説明します。これは、暗号化を行い、256の空白を埋め、パケットも送信する基本的な機能です。あなたはそれを改善したいかもしれないので、あなたはそれで少し働くことができます。

プラグインの実行中のphpのライブデモをここで見ることができます:http://topg.org/test_votifier

于 2012-11-02T16:38:49.017 に答える