首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP Socket 編程實現圖片上傳:服務端與客戶端完整示例

     編輯:PHP 綜合知識

基於 TCP Socket 的文件傳輸示例,展示服務端監聽接收、客戶端發送的完整流程,適合理解網絡編程基礎或特殊場景(如內網設備互傳)。

服務端代碼 (server.php)

<?php
set_time_limit(0); // 長運行腳本取消超時
error_reporting(E_ALL);

$host = '192.168.3.57';
$port = 1337;
$save_path = 'e:/web/'; // Windows 路徑,Linux 改為 /home/upload/

// 創建 Socket
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if (!$socket) die("socket_create 失敗: " . socket_strerror(socket_last_error()));

// 綁定地址
if (!socket_bind($socket, $host, $port)) die("socket_bind 失敗: " . socket_strerror(socket_last_error()));

// 監聽
if (!socket_listen($socket, 5)) die("socket_listen 失敗: " . socket_strerror(socket_last_error()));
echo "服務端啟動,監聽 $host:$port ...\n";

while (true) {
    // 接受連接
    $client = socket_accept($socket);
    if (!$client) continue;

    // 發送歡迎信息
    $msg = "telnet succeed!\r\n";
    socket_write($client, $msg, strlen($msg));

    $fp = null;
    $buffer = '';

    // 接收數據循環
    while ($bytes = @socket_recv($client, $buffer, 1024, 0)) {
        if ($bytes === false) break;

        // 解析文件名(簡易協議:首包含 filename:xxx)
        if ($fp === null && false !== strpos($buffer, 'filename:')) {
            $filename = trim(substr($buffer, 9)); // 9 = strlen('filename:')
            $filename = basename($filename); // 安全過濾
            $filepath = $save_path . $filename;
            $fp = fopen($filepath, 'wb');
            if (!$fp) {
                echo "無法創建文件: $filepath\n";
                break;
            }
            echo "開始接收文件: $filename\n";
            continue; // 首包不寫入文件內容
        }

        if ($fp) {
            fwrite($fp, $buffer);
        }
    }

    if ($fp) {
        fclose($fp);
        echo "文件接收完成\n";
    }
    socket_close($client);
}

socket_close($socket);
?>

客戶端代碼 (client.php)

<?php
$host = '192.168.3.57';
$port = 1337;
$local_file = '../../iphone3G.bmp';
$remote_name = 'socket_file.bmp';

$fp = fsockopen($host, $port, $errno, $errstr, 10);
if (!$fp) {
    die("連接失敗: $errstr ($errno)\n");
}

echo "連接成功\n";

// 發送文件名協議
$header = "filename:$remote_name";
fwrite($fp, $header);

// 發送文件內容
$content = file_get_contents($local_file);
if ($content === false) {
    die("讀取本地文件失敗\n");
}
fwrite($fp, $content);

// 發送結束標記(可選)
fwrite($fp, 'over');
echo "上傳完成\n";

fclose($fp);
?>

協議設計說明

簡易文本協議:

  1. 客戶端連接後發送 filename:xxx.ext
  2. 2. 服務端解析文件名,創建文件句柄 3. 後續數據包直接寫入文件 4. 連接關閉視為傳輸結束(或約定 over 結束標記)

關鍵技術點

點說明
socket_createAF_INET=IPv4, SOCK_STREAM=TCP, SOL_TCP=協議
socket_bind綁定 IP:Port,0.0.0.0 表示所有網卡
socket_listenbacklog=5 等待隊列長度
socket_accept阻塞等待客戶端連接,返回新 Socket 資源
socket_recv接收數據,flags=0 正常,MSG_WAITALL 等待滿緩衝區
socket_write發送數據,返回發送字節數
fsockopen客戶端高級封裝,返回文件指針,可用 fread/fwrite

生產環境增強建議

  1. 協議健壯化:二進制協議(長度前綴)、CRC32 校驗、分片傳輸
  2. 2. 異步非阻塞:socket_set_nonblock() + socket_select() 處理高併發 3. SSL/TLS 加密:stream_socket_enable_crypto() 或 OpenSSL 擴展 4. 進程管理:pcntl_fork() 多進程、或 Swoole/Workerman 框架 5. 文件完整性:傳輸後驗證 MD5/SHA256

Socket 編程是網絡通信基石,理解其同步阻塞模型是進階高性能網絡編程的前提。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved