• HTTP 笔记与总结(4 )socket 编程:批量发帖


    浏览器发送 POST 请求

    表单 form.html

    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
        <form action="a.php" method="post">
            username: <input type="text" name="username">
            password: <input type="password" name="password">
            <input type="submit" value="提交">
        </form>
    </body>
    </html>
    

    a.php 接收数据

    <?php
    print_r($_POST);
    

        

    HTTP POST 的请求和响应

    telnet 模拟 POST 请求

    POST /php/http/a.php HTTP/1.1
    Host: 127.0.0.17
    Content-type: application/x-www-form-urlencoded
    Content-length: 28
    
    username=dee&password=123456HTTP/1.1 200 OK
    Date: Sat, 11 Jul 2015 17:05:31 GMT
    Server: Apache/2.2.21 (Win32) PHP/5.3.10
    X-Powered-By: PHP/5.3.10
    Content-Length: 57
    Content-Type: text/html
    
    Array
         (
              [username] => dee
                                   [password] => 123456
                                                       )
    

      

    http 发送类 http.calss.php 补全 POST 请求

    测试打印拼接的 POST  请求的请求行、头信息、主体信息,代码:

    <?php
    /*
    	PHP + socket 编程
    	@发送 HTTP 请求
    	@模拟下载
    	@实现注册、登录、批量发帖
    */
    
    //http 请求类的接口
    interface Proto{
    	//连接 url 
    	function conn($url);
    
    	//发送 GET 请求
    	function get();
    
    	//发送 POST 请求
    	function post();
    
    	//关闭连接
    	function close();
    }
    
    class Http implements Proto{
    
    	//换行符
    	const CRLF = "
    ";
    
    	//fsocket 的错误号与错误描述
    	protected $errno = -1;
    	protected $errstr = '';
    
    	//响应内容
    	protected $response = '';
    
    	protected $url = null;
    	protected $version = 'HTTP/1.1';
    	protected $fh = null;
    
    	protected $line = array();
    	protected $header = array();
    	protected $body = array();
    
    	public function __construct($url){
    		$this->conn($url);
    		$this->setHeader('Host:' . $this->url['host']);
    	}
    
    	//写请求行
    	protected function setLine($method){
    		$this->line[0] = $method . ' ' . $this->url['path'] . ' ' . $this->version;
    	}
    
    	//写头信息
    	protected function setHeader($headerline){
    		$this->header[] = $headerline;
    	} 
    
    	//写主体信息
    	protected function setBody($body){
    		//构造 body 的字符串
    		$this->body[] = http_build_query($body);
    	}
    
    	//连接 url 
    	public function conn($url){
    		$this->url = parse_url($url);
    		//判断端口
    		if(!isset($this->url['port'])){
    			$this->url['port'] = 80;
    		}
    		$this->fh = fsockopen($this->url['host'], $this->url['port'], $this->errno, $this->errstr, 3);
    	}
    
    	//构造 GET 请求的数据
    	public function get(){
    		$this->setLine('GET');
    		//发送请求
    		$this->request();
    		return $this->response;
    	}
    
    	//构造 POST 请求的数据
    	public function post($body = array()){
    		//构造请求行
    		$this->setLine('POST');
    
    		//设置 Content-type 和 Content-length
    		$this->setHeader('Content-type: application/x-www-form-urlencoded');
    		
    		//构造主体信息, 和 GET 请求不一样的地方
    		$this->setBody($body);
    		
    		$this->setHeader('Content-length: ' . strlen($this->body[0]));
    
    		//发送请求
    		$this->request();
    		return $this->response;		
    	}
    
    	//发送请求
    	public function request(){
    		//把请求行、头信息、主体信息拼接起来
    		$req = array_merge($this->line, $this->header, array(''), $this->body, array(''));
    		$req = implode(self::CRLF, $req);
    		echo $req;exit;
    
    		fwrite($this->fh, $req);
    
    		while(!feof($this->fh)){
    			$this->response .= fread($this->fh, 1024);
    		}
    
    		//关闭连接
    		$this->close();
    	}
    
    	//关闭连接
    	public function close(){
    		fclose($this->fh);
    	}
    }
    
    set_time_limit(0);
    
    //$url = 'http://book.douban.com/subject/26376603/';
    $url = 'http://127.0.0.17/php/http/a.php';
    
    $http = new Http($url);
    //echo $http->get();
    
    //打乱
    $str = str_shuffle('abcdefghijklmnopqrstuvwxyz0123456789');
    $username = substr($str, 0, 5);
    $password = substr($str, 6, 12);
    
    $body = array(
    		'username'=>$username,
    		'password'=>$password
    	);
    $http->post($body);
    
    echo $username,'--',$password;
    

    输出:

      

    然后发送请求,同时配合 for 循环就可以进行(不注册且没有验证码的)批量注册(把 username 换成 title,password 换成 content,可以使用 php 的命令行工具 ,在 cmd 中执行 php.exe 文件路径)。

    使用命令行如下所示:

    完整代码:

    <?php
    /*
    	PHP + socket 编程
    	@发送 HTTP 请求
    	@模拟下载
    	@实现注册、登录、批量发帖
    */
    
    //http 请求类的接口
    interface Proto{
    	//连接 url 
    	function conn($url);
    
    	//发送 GET 请求
    	function get();
    
    	//发送 POST 请求
    	function post();
    
    	//关闭连接
    	function close();
    }
    
    class Http implements Proto{
    
    	//换行符
    	const CRLF = "
    ";
    
    	//fsocket 的错误号与错误描述
    	protected $errno = -1;
    	protected $errstr = '';
    
    	//响应内容
    	protected $response = '';
    
    	protected $url = null;
    	protected $version = 'HTTP/1.1';
    	protected $fh = null;
    
    	protected $line = array();
    	protected $header = array();
    	protected $body = array();
    
    	public function __construct($url){
    		$this->conn($url);
    		$this->setHeader('Host:' . $this->url['host']);
    	}
    
    	//写请求行
    	protected function setLine($method){
    		$this->line[0] = $method . ' ' . $this->url['path'] . ' ' . $this->version;
    	}
    
    	//写头信息
    	protected function setHeader($headerline){
    		$this->header[] = $headerline;
    	} 
    
    	//写主体信息
    	protected function setBody($body){
    		//构造 body 的字符串
    		$this->body[] = http_build_query($body);
    	}
    
    	//连接 url 
    	public function conn($url){
    		$this->url = parse_url($url);
    		//判断端口
    		if(!isset($this->url['port'])){
    			$this->url['port'] = 80;
    		}
    		$this->fh = fsockopen($this->url['host'], $this->url['port'], $this->errno, $this->errstr, 3);
    	}
    
    	//构造 GET 请求的数据
    	public function get(){
    		$this->setLine('GET');
    		//发送请求
    		$this->request();
    		return $this->response;
    	}
    
    	//构造 POST 请求的数据
    	public function post($body = array()){
    		//构造请求行
    		$this->setLine('POST');
    
    		//设置 Content-type 和 Content-length
    		$this->setHeader('Content-type: application/x-www-form-urlencoded');
    		
    		//构造主体信息, 和 GET 请求不一样的地方
    		$this->setBody($body);
    		
    		$this->setHeader('Content-length: ' . strlen($this->body[0]));
    
    		//发送请求
    		$this->request();
    		return $this->response;		
    	}
    
    	//发送请求
    	public function request(){
    		//把请求行、头信息、主体信息拼接起来
    		$req = array_merge($this->line, $this->header, array(''), $this->body, array(''));
    		$req = implode(self::CRLF, $req);
    		//echo $req;exit;
    
    		fwrite($this->fh, $req);
    
    		while(!feof($this->fh)){
    			$this->response .= fread($this->fh, 1024);
    		}
    
    		//关闭连接
    		$this->close();
    	}
    
    	//关闭连接
    	public function close(){
    		fclose($this->fh);
    	}
    }
    
    set_time_limit(0);
    
    //$url = 'http://book.douban.com/subject/26376603/';
    $url = 'http://127.0.0.17/php/http/a.php';
    
    $http = new Http($url);
    //echo $http->get();
    
    //批量
    for($i = 1; $i < 100; $i++){
    
    	//打乱
    	$str = str_shuffle('abcdefghijklmnopqrstuvwxyz0123456789');
    	$username = substr($str, 0, 5);
    	$password = substr($str, 6, 12);
    
    	$body = array(
    			'username'=>$username,
    			'password'=>$password
    		);
    	$http->post($body);
    
    	echo $username,'--',$password;
    
    	usleep(2000);
    }
    

      

  • 相关阅读:
    设计模式学习笔记——单例(Singleton)模式
    设计模式学习笔记——抽象工厂(Abstract Factory)模式
    一些C++的好书
    C++概念重载、覆盖、隐藏
    集合的子集和集合的全排列问题
    百度二面,悲剧了,附面试题,欢迎探讨。
    【翻译】ASP.NET MVC4 入门(二)添加一个Controller
    遇到问题应该多思考一下——由一个泛型方法想到的
    【翻译】ASP.NET MVC4 入门(四)添加一个Model
    我的第一篇博客——Delegate的秘密
  • 原文地址:https://www.cnblogs.com/dee0912/p/4639388.html
Copyright © 2020-2023  润新知