首页

源码搜藏网

首页 > 开发教程 > php教程 >

自己动手用PHP编写一个简单的HTTP Server(单进程版)

创建时间:2016-12-29 16:39  

HTTP协议我的简化版理解就是电脑上浏览器向服务器发送一个预先定义好的文本(Http Request)
然后服务器端处理一下(通常是从硬盘读取一个后缀名为html的文件),然后再把这个文件
通过文本方式发回去(Http Response),就这么简单。

唯一麻烦的是我得请操作系统给我建立Http层下面的TCP连接通道,因为所有的文本数据都得通过TCP管道接收和发送,这个通道是用socket建立的。

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数据。

只实现了当前目录下的html与jpg图片的解析处理,原理都类似。

 


<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();
上一篇:asp.net网站接入QQ登录
下一篇:php开发中可以防跨站请求的几种方法

相关内容

热门推荐