PHP手写HTTP协议

HTTP GET请求的格式:

GET /path HTTP/1.1
Header1: Value1
Header2: Value2
Header3: Value3

注意:每个Header一行一个,换行符是\r\n,最后一个Header 结束需要连续两个\r\n,php \r\n需要放在双引号内

下面是php socket 实现的http 访问,实测是ok的

//需要连接的域名
        $host="127.0.0.1";
        $port="80";
        //php创建socket
        $socket=socket_create(AF_INET,SOCK_STREAM,getprotobyname("tcp"));
        //链接服务器
        $req=socket_connect($socket,$host,$port);
        if ($req){
            //模拟实现HTTP GET,这里 字符串拼接需要用双引号才能转译
            $http="GET /index.php HTTP/1.1\r\n";
            $http.="Host: $host\r\n";
            $http.="Accept-Language: zh-cn\r\n";
            $http.="Connection: Keep-Alive\r\n";
            $http.="Cookie: session_id=fweiweiBFDGPERII2JHsd;username=test\r\n";
            $http.="\r\n";//header 结尾
            //模拟发送http 请求
            socket_write($socket,$http,strlen($http));
            //读取返回数据,这里一次读完
            $input = socket_read($socket, 1024*1024);
            socket_close($socket);
            echo($input);
        }

同理 POST的格式如下

POST /path HTTP/1.1
Header1: Value1
Header2: Value2
Header3: Value3
 
name=test&age=18

注意:当遇到连续两个\r\n时,Header部分结束,后面的数据全部是Body,携带了body 必须添加Content-length Header 头 并且body 数据长度必须跟其一致,通过Content-Type 表明数据格式
eg:

//需要连接的域名
        $host="127.0.0.1";
        $port="80";
        //php创建socket
        $socket=socket_create(AF_INET,SOCK_STREAM,getprotobyname("tcp"));
        //链接服务器
        $req=socket_connect($socket,$host,$port);
        if ($req){
            $data="age=111&name=0505";
            //模拟实现HTTP GET
            $http="POST /index.php HTTP/1.1\r\n";
            $http.="Host: $host\r\n";
            $http.="Accept-Language: zh-cn\r\n";
            $http.="Accept: */*\r\n";
            $http.="Connection: Keep-Alive\r\n";
            $http.="Cookie: session_id=fweiweiBFDGPERII2JHsd;username=test\r\n";
            $http.="Content-Type: application/x-www-form-urlencoded\r\n";
            $http.="Content-length: ".strlen($data)."\r\n";//需要携带数据,必须要声明内容长度
            $http.="\r\n";

            //拼接body
            $http=$http.$data;
            //模拟发送http 请求
            socket_write($socket,$http,strlen($http));
            //读取返回数据,这里一次读完
            $input = socket_read($socket, 1024*1024);
            socket_close($socket);
            echo($input);
        }

HTTP响应如果包含body,也是通过\r\n\r\n来分隔的。

Body的数据类型由Content-Type头来确定,如果是网页,Body就是文本,如果是图片,Body就是图片的二进制数据。

resporn 示例

HTTP/1.1 200 OK 
Server: nginx Date: Tue, 18 May 2021 08:10:37 GMT 
Content-Type: text/html; charset=UTF-8 Transfer-Encoding: chunked Connection: keep-alive Vary: Accept-Encoding 1b 
{"age":"111","name":"0505"} 
0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值