編程學(xué)習(xí)網(wǎng) > 編程語言 > ASP開發(fā) > 通過 Socket 實現(xiàn) HTTP 協(xié)議中的 GET 請求
2020
04-29

通過 Socket 實現(xiàn) HTTP 協(xié)議中的 GET 請求

attachments-2020-04-Hw7Kcthh5ea8e7e333fb9.jpg


請求地址: http://localhost:8091/exercise/gate.php, 提供服務(wù):

echo json_encode($_GET, JSON_UNESCAPED_UNICODE);
 

get.php

// 發(fā)送個體請求
$host = '127.0.0.1';
$port = 8091;
if(($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === FALSE)
{
exit('初始化socket資源錯誤: ' . socket_strerror(socket_last_error()));
}
if(socket_connect($sock, $host, $port) === FALSE)
{
exit('連接socket失敗: ' . socket_strerror(socket_last_error($sock)));
}
 
// 根據(jù)HTTP協(xié)議, 組裝GET請求的數(shù)據(jù)
$msg = "GET /exercise/gate.php?method=get&type=socket&version=1.0&purpose=test HTTP/1.1\r\n";
$msg .= "Host: localhost:8091\r\n";
$msg .= "Connection: close\r\n";
// 第一個\r\n是請求首部換行,第二個\r\n是一個空行,表示請求頭和請求體之間的分割空行。第三個\r\n表示請求體是空
$msg .= "Content-type: application/x-www-form-urlencoded; charset=utf-8\r\n\r\n\r\n";
 
if(socket_write($sock, $msg) === FALSE)
{
exit('發(fā)送數(shù)據(jù)失敗: ' . socket_strerror(socket_last_error($sock)));
}
 
// 讀取數(shù)據(jù)方式1
//$data = '';
//// 循環(huán)讀取指定長度的服務(wù)器響應(yīng)數(shù)據(jù)
//while($response = socket_read($sock, 4))
//{
// $data .= $response;
//}
 
// 讀取數(shù)據(jù)方式2
$byteLen = socket_recv($sock, $data, 2048, MSG_WAITALL);
 
echo $byteLen . '<hr>';
echo $data;
socket_close($sock);

通過命令行運行 get.php, 返回的響應(yīng)消息:

v2-d40d880f003eb5e99ec317d9ef876a02_720w.jpg


通過 Socket 實現(xiàn) HTTP 協(xié)議中的 POST 請求: 提交表單數(shù)據(jù)

將 http://localhost:8091/exercise/gate.php 提供的服務(wù)修改為:

echo json_encode($_POST, JSON_UNESCAPED_UNICODE);

postFormData.php

$host = 'localhost';
$port = 8091;
if(($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === FALSE)
{
exit('初始化socket資源錯誤: ' . socket_strerror(socket_last_error($sock)));
}
if(socket_connect($sock, $host, $port) === FALSE)
{
exit('連接socket失敗: ' . socket_strerror(socket_last_error($sock)));
}
 
$data = [
'type' => 'socket',
'version' => '1.0',
'purpose' => 'test'
];
$data = http_build_query($data);
$msg = "POST /exercise/gate.php HTTP/1.1\r\n";
$msg .= "Host: localhost:8091\r\n";
$msg .= "Content-type: application/x-www-form-urlencoded; charset=utf-8\r\n";
$msg .= "Connection: close\r\n";
//$msg .= "Expect: 100-continue\r\n"; // 用于詢問服務(wù)器是否接收客戶端數(shù)據(jù),服務(wù)器返回狀態(tài)碼:100 Continue時,表示接收客戶端數(shù)據(jù),可以繼續(xù)發(fā)送數(shù)據(jù)
//請求體和請求頭之間用一個空行進行分割
$msg .= "Content-Length: " . strlen($data) . "\r\n\r\n";
$msg .= $data;
 
 
 
// 先發(fā)送請求頭,詢問服務(wù)器是否接收客戶端數(shù)據(jù)
if(socket_write($sock, $msg) === FALSE)
{
exit('發(fā)送數(shù)據(jù)失敗: ' . socket_strerror(socket_last_error($sock)));
}
$response = '';
// 循環(huán)讀取指定長度的服務(wù)器響應(yīng)數(shù)據(jù)
while($info = socket_read($sock, 4))
{
$response .= $info;
}
echo $response . PHP_EOL;
socket_close($sock);

通過命令行運行 postFormData.php, 獲得的響應(yīng)消息:

v2-6459ab4f08f947f266828ea533c84058_720w.jpg


通過 Socket 實現(xiàn) HTTP 協(xié)議中的 POST 請求: 上傳附件

http://localhost:8091/exercise/gate.php提供的服務(wù)修改為:

echo json_encode($_FILES, JSON_UNESCAPED_UNICODE);
move_uploaded_file($_FILES['uploadFile']['tmp_name'], './socket/http/test.jpg');D_UNICODE);

postFile.php

$host = 'localhost';
$port = 8091;
if(($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === FALSE)
{
exit('初始化socket資源錯誤: ' . socket_strerror(socket_last_error($sock)));
}
if(socket_connect($sock, $host, $port) === FALSE)
{
exit('連接socket失敗: ' . socket_strerror(socket_last_error($sock)));
}
 
$file = file_get_contents('../488.jpg');
// 先構(gòu)建請求體,便于后面計算請求體長度
$requestBody = "------abbox\r\n";
$requestBody .= "Content-Disposition: form-data; name=\"type\"\r\n\r\n";
 
$requestBody .= "socket\r\n";
$requestBody .="------abbox\r\n";
$requestBody .= "Content-Disposition: form-data; name=\"version\"\r\n\r\n";
 
$requestBody .= "1.0\r\n";
$requestBody .="------abbox\r\n";
$requestBody .= "Content-Disposition: form-data; name='uploadFile'; filename='測試文件.jpg'\r\n";
$requestBody .="Content-Type: image/jpeg\r\n\r\n"; // 不同文件類型的Content-Type設(shè)置可以參考:https://helpcdn.aliyun.com/knowledge_detail/39522.html
 
$requestBody .= $file . "\r\n";
$requestBody .= "------abbox--";
 
$length = strlen($requestBody);
 
$requestHeader = "POST /exercise/gate.php HTTP/1.1\r\n";
$requestHeader .= "Host: 127.0.0.1:8091\r\n";
$requestHeader .= "Cache-Control: no-cache\r\n";
$requestHeader .= "Content-Length: {$length}\r\n"; // Content-Length 請求體長度不可省略
$requestHeader .= "Connection: close\r\n";
$requestHeader .= "Content-Type:multipart/form-data; boundary=----abbox\r\n\r\n";
 
$request = $requestHeader . $requestBody;
 
if(socket_write($sock, $request) === FALSE)
{
exit('發(fā)送數(shù)據(jù)失敗: ' . socket_strerror(socket_last_error($sock)));
}
$data = '';
// 循環(huán)讀取指定長度的服務(wù)器響應(yīng)數(shù)據(jù)
while($response = socket_read($sock, 4))
{
$data .= $response;
}
echo $data . PHP_EOL;
socket_close($sock);


通過命令行運行 postFile.php, 響應(yīng)消息如下:

v2-8071312e7622a433bd91af5e098c5469_720w.jpg


成功接收到服務(wù)端返回的上傳文件信息, 且已將上傳文件保存到 test.jpg:

v2-3d434ba20dc19f0d63ac5ee432d048b8_720w.jpg


attachments-2020-04-4Ur03BpV5ea8e7907fdd0.jpg

掃碼二維碼 獲取免費視頻學(xué)習(xí)資料

Python編程學(xué)習(xí)

查 看2022高級編程視頻教程免費獲取