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

网友投稿 736 2022-08-19

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

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

请求地址: 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 . '

echo $data;

socket_close($sock);

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

通过 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, 获得的响应消息:

通过 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, 响应消息如下:

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

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:为什么大厂都在用 GO 语言?读透 GO 语言的切片
下一篇:Go语言 Yaml编码和解码(go语言和c++有什么区别)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~