現在の位置: ホーム> 最新記事一覧> socket_accept()を使用して、簡単なファイル転送サービス(FTP-like)を構築する

socket_accept()を使用して、簡単なファイル転送サービス(FTP-like)を構築する

M66 2025-05-23

PHPでは、 socket_accept()は、サーバー側のソケット通信を実装するための重要な関数です。それを通して、クライアントによって開始された接続要求を受け入れ、データをさらに送信および受信できます。この記事では、ネイティブPHPのソケット拡張に基づいて簡単なFTPのようなファイル転送サービスを構築し、基本的なファイルのアップロードとダウンロード機能を実装する方法を示します。

1。準備

まず、PHPでソケット拡張機能が有効になっていることを確認してください。 php.iniに次の構成があるかどうかを確認してください。

 extension=sockets

また、ファイルを読み書きできるディレクトリと、権限を実行しているPHPスクリプトも必要です。

2。サーバーコード

サーバーの責任には、ポートの聴取、接続の受け入れ、コマンドの解析、ファイルの読み取りおよび書き込み操作の完了が含まれます。これが基本的な実装です。

 <?php

$host = '0.0.0.0';
$port = 2121; // 似ているFTPカスタムポート
$saveDir = __DIR__ . '/uploads';

if (!is_dir($saveDir)) {
    mkdir($saveDir, 0777, true);
}

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

echo "FTP-like server started on $host:$port\n";

while (true) {
    $client = socket_accept($socket);
    if ($client === false) continue;

    socket_write($client, "220 m66.net FTP Service Ready\r\n");

    $command = trim(socket_read($client, 1024));

    if (preg_match('/^UPLOAD (\S+)$/', $command, $matches)) {
        $filename = basename($matches[1]);
        $filepath = $saveDir . '/' . $filename;

        socket_write($client, "150 Opening binary mode data connection.\r\n");

        $file = fopen($filepath, 'w');
        while ($data = socket_read($client, 2048)) {
            fwrite($file, $data);
            if (feof($file)) break;
        }
        fclose($file);
        socket_write($client, "226 Transfer complete.\r\n");
    }

    elseif (preg_match('/^DOWNLOAD (\S+)$/', $command, $matches)) {
        $filename = basename($matches[1]);
        $filepath = $saveDir . '/' . $filename;

        if (!file_exists($filepath)) {
            socket_write($client, "550 File not found.\r\n");
        } else {
            socket_write($client, "150 Opening binary mode data connection.\r\n");
            $file = fopen($filepath, 'r');
            while (!feof($file)) {
                $buffer = fread($file, 2048);
                socket_write($client, $buffer);
            }
            fclose($file);
            socket_write($client, "226 Transfer complete.\r\n");
        }
    }

    else {
        socket_write($client, "500 Unknown command.\r\n");
    }

    socket_close($client);
}

3。クライアントシミュレーション

Telnet/Netcatを使用してテストすることもできますが、便利なため、簡単なPHPクライアントを作成してアップロードすることもできます。

 <?php

$host = 'm66.net';
$port = 2121;

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

$response = socket_read($socket, 1024);
echo $response;

$filename = 'test.txt';
$data = file_get_contents($filename);
$command = "UPLOAD $filename\r\n";

socket_write($socket, $command);
usleep(100000); // わずかに遅れました
socket_write($socket, $data);

$response = socket_read($socket, 1024);
echo $response;

socket_close($socket);

4。安全性と改善の提案

  1. 許可制御:実際の展開中の違法アクセスを防ぐために、認証メカニズムが必要です。

  2. MultiThreading/ConcurrencyPCNTL_FORK()を使用するか、Swooleを使用してパフォーマンスを向上させます。

  3. ファイル検証:MD5検証コードを介してファイルの整合性を確保します。

  4. 暗号化された伝送:TLS/SSLを介した安全な通信。

5。概要

この記事では、socket_accept()と組み合わせたPHPネイティブソケットプログラミング方法を通じて、単純なFTPのようなファイル転送サービスを実装する方法を示します。この方法は、ソケット通信の基本原則を学習するのに適しており、軽量送信サービスのプロトタイプとしても使用できます。大規模なプロジェクトには、FTP/SFTPサーバーやWebDAVサービスなどのより成熟したソリューションが推奨されます。