短文1.1:使用 php-socket 簡述 http 伺服器原理

php_yt發表於2020-12-27

此節使用 PHP 原生 Socket 演示完成 http 請求的原理

一個典型的網路連線由 2 個套接字構成,一個執行在客戶端,另一個執行在伺服器端。

“套接字”取名叫做 socket,翻譯:“插座”。在網路程式設計中叫做用於網路資料傳輸的“軟體裝置”。

那麼通俗理解一點,“套接字” 就是一個檔案資源 file

socket 示意圖

建立一個套接字,$server 表示的是服務端的套接字。

$server = socket_create(
AF_INET, 
SOCK_STREAM, 
SOL_TCP);

繫結埠號

socket_bind($socket, '0.0.0.0', 80);

開始監聽

socket_listen($socket, 5);

與一個客戶端建立連線

$client = socket_accept($server);

讀取客戶端訊號

$buf = socket_read($client, 1024);

處理訊號

$response = 'hello! i am server!';
$http_resonse = "HTTP/1.1 200 OK\r\n"; $http_resonse .= "Content-Type: text/html;charset=UTF-8\r\n"; $http_resonse .= "Connection: keep-alive\r\n"; $http_resonse .= "Server: php socket server\r\n"; $http_resonse .= "Content-length: ".strlen($content)."\r\n\r\n"; $http_resonse .= $content;

向客戶端寫入訊號

socket_write($client,$http_resonse);

關閉客戶端

socket_close($client);

關閉服務端

socket_close($server);

上邊讀取到客戶端的訊號buf,如果我請求的地址是這樣:
請求  URL
列印buf:
socket 列印buf
buf是一長串字串,用正則來匹配該字串:

$preg = '#GET (.*) HTTP/1.1#iU';
preg_match($preg, $buf, $arr);
$request = $arr[1];

匹配的 (.*)是:
uri
這樣我們就拿到了請求的內容。
如果是載入靜態頁面:
靜態頁面
獲取的檔名是
靜態頁面檔名
那麼 $response是:

$filePath = __DIR__ . '/html' . $path;
$content = file_get_contents($filePath);

如果是 php 檔案:
請求的是php檔案
獲取的檔名是:
獲取的檔名是
那麼 $response 是:

$filePath = __DIR__ . '/php' . $path;
ob_start();
include $filePath;
$content = ob_get_contents();
ob_clean();
本作品採用《CC 協議》,轉載必須註明作者和本文連結
focus

相關文章