page contents

通过 Socket 实现 HTTP 协议中的 GET 请求

以下内容希望帮助到大家下

attachments-2020-04-Hw7Kcthh5ea8e7e333fb9.jpg

请求地址: http://localhost:8091/exercise/gate.php, 提供服务:

echo json_encode($_GET, JSON_UNESCAPED_UNICODE);
 

get.php

// 发送个体请求
$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)));
}
 
// 根据HTTP协议, 组装GET请求的数据
$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('发送数据失败: ' . socket_strerror(socket_last_error($sock)));
}
 
// 读取数据方式1
//$data = '';
//// 循环读取指定长度的服务器响应数据
//while($response = socket_read($sock, 4))
//{
// $data .= $response;
//}
 
// 读取数据方式2
$byteLen = socket_recv($sock, $data, 2048, MSG_WAITALL);
 
echo $byteLen . '<hr>';
echo $data;
socket_close($sock);

通过命令行运行 get.php, 返回的响应消息:

v2-d40d880f003eb5e99ec317d9ef876a02_720w.jpg


通过 Socket 实现 HTTP 协议中的 POST 请求: 提交表单数据

将 http://localhost:8091/exercise/gate.php 提供的服务修改为:

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"; // 用于询问服务器是否接收客户端数据,服务器返回状态码:100 Continue时,表示接收客户端数据,可以继续发送数据
//请求体和请求头之间用一个空行进行分割
$msg .= "Content-Length: " . strlen($data) . "\r\n\r\n";
$msg .= $data;
 
 
 
// 先发送请求头,询问服务器是否接收客户端数据
if(socket_write($sock, $msg) === FALSE)
{
exit('发送数据失败: ' . socket_strerror(socket_last_error($sock)));
}
$response = '';
// 循环读取指定长度的服务器响应数据
while($info = socket_read($sock, 4))
{
$response .= $info;
}
echo $response . PHP_EOL;
socket_close($sock);

通过命令行运行 postFormData.php, 获得的响应消息:

v2-6459ab4f08f947f266828ea533c84058_720w.jpg


通过 Socket 实现 HTTP 协议中的 POST 请求: 上传附件

http://localhost:8091/exercise/gate.php提供的服务修改为:

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');
// 先构建请求体,便于后面计算请求体长度
$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设置可以参考: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('发送数据失败: ' . socket_strerror(socket_last_error($sock)));
}
$data = '';
// 循环读取指定长度的服务器响应数据
while($response = socket_read($sock, 4))
{
$data .= $response;
}
echo $data . PHP_EOL;
socket_close($sock);


通过命令行运行 postFile.php, 响应消息如下:

v2-8071312e7622a433bd91af5e098c5469_720w.jpg


成功接收到服务端返回的上传文件信息, 且已将上传文件保存到 test.jpg:

v2-3d434ba20dc19f0d63ac5ee432d048b8_720w.jpg


attachments-2020-04-4Ur03BpV5ea8e7907fdd0.jpg

  • 发表于 2020-04-29 10:35
  • 阅读 ( 656 )
  • 分类:PHP开发

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
Pack
Pack

1135 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1316 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章