Http.php实现http请求,PHP+socket请求原理
来源:原创
时间:2016-07-23
作者:脚本小站
分类:代码笔记
<?php //============================================================ //-------------------------HTTP------------------------------- /* webservice = http协议 + XML Rest = HTTP协议 + json ... 协议有 ftp http stmp pop tcp/ip 等 */ //------------------------------------------------------------ //---------------HTTP请求信息和响应信息的格式---------------- /* 请求: 1.请求行 (1)请求方法 GET POST HEAD PUT DELETE TRACE OPTIONS (2)请求路径 http.php (3)所用协议 HTTP/1.1 2.请求头信息 Host: localhost 3.请求主体信息 注意:头信息和主体信息要空一行 响应: 1.响应行 (1)协议版本 HTTP/1.1 200 OK (2)状态码 200 (3)状态文字 OK 2.响应头信息 健名:健值 key:value Content-Length:12 3.响应主体信息 */ //------------------------------------------------------------ //-----------------DOS窗口发送HTTP请求方法------------------- /* 1. ipconfig命令查看本机IP IPv4 地址 . . . . . . . . . . . . : 192.168.1.101 2. telnet 192.168.1.101 80 打开80端口 3. 用 ctrl + ] 再回车 打开回显功能 4. 输入如下内容: GET /http.php HTTP/1.1 Host: localhost Content-length: 23 username=admin&pass=123 (两次回车) 然后可看到如下的请求信息 HTTP/1.1 200 OK Date: Fri, 04 Mar 2016 06:56:41 GMT Server: Apache/2.4.10 (Win32) OpenSSL/0.9.8zb mod_fcgid/2.3.9 X-Powered-By: PHP/5.4.33 Transfer-Encoding: chunked Content-Type: text/html ok这是返回的信息 5.post请求时请求头信息中要加 Content-type: application/x-www-form-urlencoded 示例: POST /http.php HTTP/1.1 Host: localhost Content-type: application/x-www-form-urlencoded Content-length: 25 demo=admin1&test=ppppoopp 问题解决: “telnet 不是内部命令” 解决方法: 控制面板->程序->打开或关闭Windows功能,勾上telnet客户端 */ //------------------------------------------------------------ //--------------------常见请求方法解释----------------------- /* HEAD 查看请求的地址是否正常 PUT 向服务器传输内容 TRACE 代理访问时查看是否修改请求 OPTION 查看服务器允许的请求方法 */ //------------------------------------------------------------ //--------------------常见状态码解释------------------------- /* 1XX 接收到请求继续处理(预留扩展使用) 2XX 成功 3XX 重定向 4XX 客户端错误 5XX 服务器端错误 200 服务器返回网页 301/302 永久/临时重定向 永久重定向: header('Location:http://www.chuxiangyi.com',true,301); 304 Not Modified 未修改(取缓存) 文件比对信息,缓存是否被修改,请求头信息中添加 If-Modified-Since:Fri, 26 Feb 2016 07:46:08 GMT If-None-Match:"3000652404" 307 重定向中保持原有的数据(防止post请求时数据丢失) header('Location:http://www.chuxiangyi.com',true,307); 404 请求页面不存在 503 服务器暂时不可以 500 服务器内部错误 */ //------------------------------------------------------------ //-------------------PHP + socket请求原理--------------------- /* $fp = fsockopen('192.168.1.101',80, $errno, $errstr, 30); if (!$fp){ echo "$errstr ($errno)<br />\n"; }else{ $out = "GET /demo.php HTTP/1.1\r\n"; $out .= "Host: localhost\r\n"; $out .= "Connection: Close\r\n\r\n"; fwrite($fp, $out); while (!feof($fp)){ echo fgets($fp, 128); } fclose($fp); } */ //------------------------------------------------------------ //------------------------------------------------------------
示例:
<?php class web_config { // 监听的端口号 const PORT = 9003; // 项目根目录 const WEB_ROOT = "/var/www/html"; } class server { private $ip; private $port; public function __construct($ip, $port) { $this->ip = $ip; $this->port = $port; $this->await(); } private function await() { $sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); if ($sock < 0) { echo "Error:" . socket_strerror(socket_last_error()) . "\n"; } $ret = socket_bind($sock, $this->ip, $this->port); if (!$ret) { echo "BIND FAILED:" . socket_strerror(socket_last_error()) . "\n"; exit; } echo "OK\n"; $ret = socket_listen($sock); if ($ret < 0) { echo "LISTEN FAILED:" . socket_strerror(socket_last_error()) . "\n"; } do { $new_sock = null; try { $new_sock = socket_accept($sock); } catch (Exception $e) { echo $e->getMessage(); echo "ACCEPT FAILED:" . socket_strerror(socket_last_error()) . "\n"; } try { $request_string = socket_read($new_sock, 1024); $response = $this->output($request_string); socket_write($new_sock, $response); socket_close($new_sock); } catch (Exception $e) { echo $e->getMessage(); echo "READ FAILED:" . socket_strerror(socket_last_error()) . "\n"; } } while (TRUE); } /** * @param $request_string * @return string */ private function output($request_string){ // 静态 GET /1.html HTTP/1.1 ... $request_array = explode(" ",$request_string); if(count($request_array) < 2){ return $this->not_found(); } $uri = $request_array[1]; $filename = web_config::WEB_ROOT . $uri; echo "request:".$filename."\n"; // 静态文件的处理 if (file_exists($filename)) { return $this->add_header(file_get_contents($filename)); } else { return $this->not_found(); } } /** * 404 返回 * @return string */ private function not_found(){ $content = "<h1>File Not Found </h1>"; return "HTTP/1.1 404 File Not Found\r\nContent-Type: text/html\r\nContent-Length: ".strlen($content)."\r\n\r\n".$content; } /** * 加上头信息 * @param $string * @return string */ private function add_header($string){ return "HTTP/1.1 200 OK\r\nContent-Length: ".strlen($string)."\r\nServer: mengkang\r\n\r\n".$string; } } $server = new server("0.0.0.0", web_config::PORT);