使用scoket发送HTTP请求

来源:互联网 发布:财务开票软件安装 编辑:程序博客网 时间:2024/05/18 18:04

建议先看一下如何用telnet发送HTTP请求:
http://blog.csdn.net/whd526/article/details/75042691

http.class.php

<?phpclass Http{    const CRLF = "\r\n";    protected $errno = -1;    protected $errstr = '';    protected $url = null;    protected $version = 'HTTP/1.1';    protected $fh = null;    protected $line = array();    protected $header = array();    protected $body = array();    protected $response = '';    public function __construct($url){        $this->conn($url);        $this->setHeader('Host',$this->url['host']);    }    /**    *此方法负责写请求行    *如 GET /index.php HTTP/1.1    */    private function setLine($method){        $this->line[0] = $method.' '.$this->url['path'].$this->url['query'].' '.$this->version;    }    /**    *此方法负责写头信息    *如Host: localhost    */    public function setHeader($key,$value){        $this->header[] = $key.': '.$value;    }    /**    *此方法负责写POST主体信息    *key=value的形式写进数组    *用http_build_query()封装成key1=value1&key2=value2    */    public function setBody($key,$value){        //$this->body[] = $key.'='.$value;        $this->body[$key] = $value;    }    /**    *用fsockopen打开网络连接    *就像telnet 192.168.0.0 80    */    private function conn($url){        //parse_url解析地址,返回其组成部分        $this->url = parse_url($url);        //如果URL没有port,则默认80端口        if(!isset($this->url['port'])){            $this->url['port'] = '80';        }        //如果URL没有path,则默认根路径'/'        //如www.baidu.com没有path        //如http://news.baidu.com/sports,path为/sports        if(!isset($this->url['path'])){            $this->url['path'] = '/';        }        if(!isset($this->url['query'])){            $this->url['query'] = '';        }else{            $this->url['query'] = '?'.$this->url['query'];        }        //打开网络连接        $this->fh = fsockopen($this->url['host'],$this->url['port'],$this->errno,$this->errstr,3);        if(!$this->fh){            echo "ERROR:$errno-$errstr";            exit;        }    }    public function get(){        $this->setLine('GET');        $this->body='';        $this->request();        return $this->response;    }    public function post(){        $this->setLine('POST');        $this->setHeader('Content-type','application/x-www-form-urlencoded');        $this->body = http_build_query($this->body);        //var_dump($this->body);exit();        $this->setHeader('Content-length',strlen($this->body));        $this->request();        return $this->response;    }    /**    *拼接请求信息,并写入response    */    private function request(){        $req = array_merge($this->line,$this->header,array(''),array($this->body),array(''));        //var_dump($req);exit;        $req = implode(self::CRLF,$req);        //print_r($req);exit;        fwrite($this->fh, $req);        while(!feof($this->fh)){            $this->response .= fread($this->fh, 1024);        }        $this->close();    }    /**    *关闭socket连接    */    public function close(){        fclose($this->fh);    }}//GET请求// $url = 'http://www.baidu.com';// $http = new Http($url);// $http->setHeader('Connection','close');// echo $http->get();//POST请求// $url = 'http://localhost/tel2.php';// $http = new Http($url);// $http->setHeader('Connection','close');// $http->setBody('username','Edward');// $http->setBody('age','20');// $http->setBody('submit','提交');// echo $http->post();?>

为什么要在头信息设置Connection:close
如果不设置Connection:close,会发现速度非常慢,feof不能准确判断是否已经得到了所有的数据,直到超过设置的超时时间才结束。

Connection的状态有两种,一种是keep-alive 另外一种就是close。
keep-alive就是保持客户端与服务器的连接,这是默认的方式。
close表示服务器给客户端发送信息之后就断开了,.close对资源消耗占用的少一些。
再完善一点,其实这和TCP三次握手有关,如果返回的是keep-alive表示之前的握手还可以用在接下来的请求当中去,如果是close的话当前请求完成后会进行四次握手关闭连接,在接下来的请求就要重新握手,这是HTTP/1.1相对1.0新增的一个部分,加快了网络传输。

实战:
用HTTP请求,往电驴发送站内信(http://home.verycd.com/cp.php?ac=pm)
先注册登录,然后在线发送一遍,用谷歌浏览器的开发者模式观察请求头信息,至于具体的抓包细节就不一一赘述了

<?phprequire('./http.class.php');$url = 'http://home.verycd.com/cp.php?ac=pm&op=send&touid=0&pmid=0';$http = new Http($url);$http->setHeader('Connection','close');$http->setHeader('Accept','text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8');$http->setHeader('Accept-Encoding','gzip, deflate');$http->setHeader('Accept-Language','zh-CN,zh;q=0.8');$http->setHeader('Cookie','xxxx');//自己的cookie$http->setHeader('Referer','http://home.verycd.com/cp.php?ac=pm&op=send&touid=0&pmid=0');$http->setHeader('User-Agent','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36');$http->setBody('username','test');$http->setBody('message','robot2222');$http->setBody('refer','');$http->setBody('pmsubmit','true');$http->setBody('pmsubmit_btn','发送');$http->setBody('formhash','16f835b2');$http->post();echo "ok";?>
原创粉丝点击