現在の位置: ホーム> 最新記事一覧> straceまたはnetstatを使用して、socket_accept()リスニングステータスの問題をトラブルシューティングします

straceまたはnetstatを使用して、socket_accept()リスニングステータスの問題をトラブルシューティングします

M66 2025-06-03

PHPを使用してソケットベースのサーバーアプリケーションを作成する場合、 socket_accept()はクライアント接続を受信する重要な関数です。ただし、いくつかのシナリオでは、プログラムロジックが正しい場合でも、 socket_accept()は正常に接続を受信しない場合があります。この記事では、 StraceおよびNetstatツールを使用して、この問題を迅速に見つけて解決する方法について説明します。

1。前提条件:典型的なPHPソケットサーバーの例

以下は、ポート8080に耳を傾ける簡単なPHPサーバープログラムです。

 <?php
$host = '0.0.0.0';
$port = 8080;

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, $host, $port);
socket_listen($socket);

echo "Server listening on $host:$port\n";

while (true) {
    $client = socket_accept($socket);
    if ($client === false) {
        echo "Failed to accept connection\n";
        continue;
    }

    $msg = "Hello from server\n";
    socket_write($client, $msg, strlen($msg));
    socket_close($client);
}
?>

socket_accept()がスタックしているか、常にfalseを返す場合、システムツールを使用して詳細なトラブルシューティングを実行する必要があります。

2。Straceを使用してシステムコールを追跡します

Straceは、Linuxの下のシステムコールトラッキングツールです。実行時にPHPスクリプトと実行結果によって呼び出されるシステムの基礎関数がどのシステムを表示するかを直接表示できます。

ステップ:

  1. たとえばPSを使用するなど、実行中のPHPプロセスPIDを見つけます:

     ps aux | grep php
    
  2. Straceを使用してプロセスに接続します。

     strace -p <PID> -e trace=network
    
  3. 次の動作が出力に存在するかどうかを観察します。

    • Accept(...)= -1 :システムコールが失敗しました。通常、エラーコード(イーガインエコナボートなど)が伴います。

    • 聞く(...)またはバインド(...)エラー:ポートが占有されているか、許可が不十分であることを意味する場合があります

    • 承認する呼び出しはありません() :プログラムは他の場所で立ち往生する可能性があります

StraceがAccept()が正常であるが接続アクセスがないことを示す場合、問題はネットワークレイヤーまたはファイアウォールにある可能性があります。

3. NetStatまたはSSを使用して、リスニングステータスを確認します

NetStatおよびSSを使用して、ポートがリスニング状態にあるかどうか、および接続が確立されているかどうかを確認できます。

リスニングステータスを確認してください:

 netstat -tlnp | grep :8080

または:

 ss -tlnp | grep :8080

次のような出力を見ることができるはずです。

 tcp    LISTEN     0      128    0.0.0.0:8080    0.0.0.0:*     users:(("php",pid=12345,fd=3))
  • リスニングがない場合、 socket_bind()またはsocket_listen()が失敗します。

  • リスニングが正常であるが接続がない場合、クライアントが接続を開始していないか、ファイアウォールによって傍受される可能性があります。

  • ステータスがclose_waitまたはtime_waitの場合、接続ライフサイクルが異常に終了することを意味します。

4.さらなるデバッグの提案

  1. エラーメッセージを確認してください<br> 各ソケット呼び出しの後、 socket_strerror(socket_last_error())を使用して、特定のエラー情報を表示します。

  2. ファイアウォールまたはSelinuxの制限<br> IPTablesまたはFirewalldを使用して、8080ポートがブロックされていないことを確認します。

  3. ポートは他のプログラム<br>によって占有されています LSOF -I:8080を使用して、他のプログラムがポートを占めるかどうかを確認します。