HTTP协议个人简化版理解就是电脑上浏览器向服务器发送一个预先定义好的文本(Http Request)
而后服务器端处理一下(一般是从硬盘读取一个后缀名为html的文件),而后再把这个文件
经过文本方式发回去(Http Response),就这么简单。php惟一麻烦的是我得请操做系统给我创建Http层下面的TCP链接通道,由于全部的文本数据都得
经过TCP管道接收和发送,这个通道是用socket创建的。html
伪代码以下web
socketMain= socket(...) bind(socketMain,主机的IP和端口号) listen(socketMain,...) 无限循环 while(true) { socketAccept = accept(socketMain,....) receive(socketAccept,....) send(socketAccept...) close(socketAccept...) }
伪代码解释浏览器
这些socket,bind,listen,accept都是操做系统提供的接口,咱们要作的就是把这些进行
组装;如今80或者其余端口监听,而后进入无限循环,若是有请求进来,就接受(accept),建立新的socket,最后经过这个socket来接收和发送Http数据。服务器
实现的php代码以下socket
只实现了当前目录下的html与jpg图片的解析处理,原理都相似。this
<?php set_time_limit(0); class HttpServer { private $ip = '127.0.0.1'; private $port = 9996; private $_socket = null; public function __construct() { $this->_socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); if ($this->_socket === false) { die(socket_strerror(socket_last_error($this->_socket))); } } public function run() { socket_bind($this->_socket, $this->ip, $this->port); socket_listen($this->_socket, 5); while(true) { $socketAccept = socket_accept($this->_socket); $request = socket_read($socketAccept, 1024); echo $request; socket_write($socketAccept, 'HTTP/1.1 200 OK'.PHP_EOL); socket_write($socketAccept, 'Date:'.date('Y-m-d H:i:s').PHP_EOL); $fileName = $this->getUri($request); $fileExt = preg_replace('/^.*\.(\w+)$/', '$1', $fileName); $fileName = __DIR__.'/'.$fileName; switch ($fileExt) { case "html": //set content type socket_write($socketAccept, 'Content-Type: text/html'.PHP_EOL); socket_write($socketAccept, ''.PHP_EOL); $fileContent = file_get_contents($fileName); socket_write($socketAccept, $fileContent, strlen($fileContent)); break; case "jpg": socket_write($socketAccept, 'Content-Type: image/jpeg'.PHP_EOL); socket_write($socketAccept,''.PHP_EOL); $fileContent = file_get_contents($fileName); socket_write($socketAccept, $fileContent, strlen($fileContent)); break; } socket_write($socketAccept, 'web serving', strlen('web serving')); socket_close($socketAccept); } } protected function getUri($request = '') { $arrayRequest = explode(PHP_EOL, $request); $line = $arrayRequest[0]; $file = trim(preg_replace('/(\w+)\s\/(.*)\sHTTP\/1.1/i','$2', $line)); return $file; } public function close() { socket_close($this->_socket); } } $httpServer = new HttpServer(); $httpServer->run();