PHPでは、 socket_accept()は、サーバー側のソケット通信を実装するための重要な関数です。それを通して、クライアントによって開始された接続要求を受け入れ、データをさらに送信および受信できます。この記事では、ネイティブPHPのソケット拡張に基づいて簡単なFTPのようなファイル転送サービスを構築し、基本的なファイルのアップロードとダウンロード機能を実装する方法を示します。
まず、PHPでソケット拡張機能が有効になっていることを確認してください。 php.iniに次の構成があるかどうかを確認してください。
extension=sockets
また、ファイルを読み書きできるディレクトリと、権限を実行しているPHPスクリプトも必要です。
サーバーの責任には、ポートの聴取、接続の受け入れ、コマンドの解析、ファイルの読み取りおよび書き込み操作の完了が含まれます。これが基本的な実装です。
<?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);
}
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);
許可制御:実際の展開中の違法アクセスを防ぐために、認証メカニズムが必要です。
MultiThreading/Concurrency : PCNTL_FORK()を使用するか、Swooleを使用してパフォーマンスを向上させます。
ファイル検証:MD5検証コードを介してファイルの整合性を確保します。
暗号化された伝送:TLS/SSLを介した安全な通信。
この記事では、socket_accept()と組み合わせたPHPネイティブソケットプログラミング方法を通じて、単純なFTPのようなファイル転送サービスを実装する方法を示します。この方法は、ソケット通信の基本原則を学習するのに適しており、軽量送信サービスのプロトタイプとしても使用できます。大規模なプロジェクトには、FTP/SFTPサーバーやWebDAVサービスなどのより成熟したソリューションが推奨されます。