http服務是創建在tcp服務之上的,它是tcp/ip協議的應用,前面咱們已經實現了tcp服務,而且使用三種不一樣的方式鏈接tcp服務javascript
既然http也是tcp應用層的一種,那麼咱們直接使用瀏覽器來鏈接tcp服務可不能夠?答案是能夠的,只不過鏈接以後直接返回給瀏覽器的信息,瀏覽器不可以正確的識別出來。那麼怎麼才能讓瀏覽器正確的識別tcp服務返回的信息呢?php
這個時候咱們就須要使用到http協議啦,至於http傳輸中都傳了哪些信息能夠在瀏覽器中 f12 查看css
目錄結構:html
http_serv.php文件java
<?php /** * Http 服務器類 */ class Http{ private $host; private $port; private $_root; public $mime_types = array( 'avi' => 'video/x-msvideo', 'bmp' => 'image/bmp', 'css' => 'text/css', 'doc' => 'application/msword', 'gif' => 'image/gif', 'htm' => 'text/html', 'html' => 'text/html', 'ico' => 'image/x-icon', 'jpe' => 'image/jpeg', 'jpeg' => 'image/jpeg', 'jpg' => 'image/jpeg', 'js' => 'application/x-javascript', 'mpeg' => 'video/mpeg', 'ogg' => 'application/ogg', 'png' => 'image/png', 'rtf' => 'text/rtf', 'rtx' => 'text/richtext', 'swf' => 'application/x-shockwave-flash', 'wav' => 'audio/x-wav', 'wbmp' => 'image/vnd.wap.wbmp', 'zip' => 'application/zip', ); /** * @param string $host 監聽地址 * @param int $port 監聽端口 * @param string $_root 網站根目錄 */ public function __construct($host,$port,$_root){ $this->host = $host; $this->port = $port; $this->_root = $_root; } /** * 啓動http服務 */ public function start(){ //建立socket套接字 $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); //設置阻塞模式 socket_set_block($socket); //爲套接字綁定ip和端口 socket_bind($socket,$this->host,$this->port); //監聽socket socket_listen($socket,4); while(true) { //接收客戶端請求 if(($msgsocket = socket_accept($socket)) !== false){ //讀取請求內容 $buf = socket_read($msgsocket, 9024); preg_match("/\/(.*) HTTP\/1\.1/",$buf,$matchs); preg_match("/Accept: (.*?),/",$buf,$matchss); //獲取接收文件類型 $type = explode("/",$matchss[1])[0]; if($type=="text"){ $content = $this->GetString($matchs[1]); }else{ $content = $this->GetImg($matchs[1]); } socket_write($msgsocket,$content,strlen($content)); socket_close($msgsocket); } } } /** * 組裝消息頭信息模板 * @param int $code 狀態碼 * @param string $status 狀態名稱 * @param string $content 發送的文本內容 * @param string $content_type 發送的內容類型 * @return string **/ public function GetHeaders($code,$status,$content="",$content_type="text/html;charset=utf-8"){ $header = ''; $header .= "HTTP/1.1 {$code} {$status}\r\n"; $header .= "Date: ".gmdate('D, d M Y H:i:s T')."\r\n"; $header .= "Content-Type: {$content_type}\r\n"; $header .= "Content-Length: ".strlen($content)."\r\n\r\n";//必須2個\r\n表示頭部信息結束 $header .= $content; return $header; } /** * 組裝文本發送信息 * @param string $url_path * @return string **/ public function GetString($url_path){ if($this->getRealPath($url_path)){ if(is_readable($this->getRealPath($url_path))){ return $this->GetHeaders(200,"OK",file_get_contents($this->getRealPath($url_path)),$this->getMime($url_path)); }else{ return $this->GetHeaders(401,"Unauthorized"); } }else{ return $this->GetHeaders(404,"Not Found"); } } /** * 組裝資源返回信息 * @param string $url_path * @return string **/ public function GetImg($url_path){ if($this->getRealPath($url_path)){ return $this->GetHeaders(200,"OK",file_get_contents($this->getRealPath($url_path)),$this->getMime($url_path)); }else{ return $this->GetHeaders(404,"Not Found"); } } /** * 獲取資源類型 * @param string $path * @return mixed */ public function getMime($path){ $type = explode(".",$path); $mime = $this-> mime_types[$type[1]]; return $mime; } /** * 獲取訪問資源的真實地址 * @param $url_path * @return bool|string */ public function getRealPath($url_path){ return realpath($this->_root."/".$url_path); } } $server = new Http("127.0.0.1",3046,"wwwroot"); $server->start();
效果圖:git
github地址: https://github.com/enjoysmilehappy/http_servergithub