java.net-CSDN刷阅读数(访问量)的小程序

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_40918961/article/details/93628023

前言:CSDN的访问量只要访问页面(get)就算一次,每次访问需要间隔一段时间,不依据IP判别,不依据用户判别,也不依据点击进行判别,因此只要通过https get请求一次就算访问一次,因此可以以此刷访问量,当然这没什么意义,只是通过这个过程了解一下通过java进行网络编程的过程及概念,具体的,了解javax.net处理过程。

1.怎样访问页面

 可以使用java.net.Socket,socket 是一种最原始的实现方式

        Socket可以建立两个终端之间的通信,将端口port设为80,即使实现了向服务器发送http请求。

我们这里使用URLConnection

      URLConnection 是一个抽象类,它代表应用程序和 URL 之间的通信链接。此类的实例可用于读取和写入此 URL 引用的资源。

    其子类HttpUrlConnection与HttpsUrlConnection分别代表使用http或https读写引用资源(类似于,先配置请求方式,再访问资源页面,参考restful概念:https://www.runoob.com/w3cnote/restful-architecture.html)。

    具体的,1.构造一个URL对象(相当于该对象代表一个网址)

                   2.如果使用https,需要先配置安全访问证书,如ssl

                   3.通过在 URL 上调用 openConnection 方法创建连接对象。

                   4.配置连接对象(调用各种setter方法),即配置http/https 访问参数和请求属性

                   5.调用连接对象的connect方法建立tcp连接,此步只建立了tcp连接,并未发送请求

                   6.调用连接对象的getInputStream()方法发送http请求,并获取响应数据。

 注意事项:

       1.URLConnection的connect()函数,实际上只是建立了一个与服务器的tcp连接,并没有实际发送http请求。
http/https请求实际上在调用HttpURLConnection的getInputStream()这个方法后才正式发送出去。
       2.在用POST方式发送URL请求时,URL请求参数的设定顺序是重中之重, 对connection对象的处理设置参数和一般请求属性和写入提交数据都必须要在connect()函数执行之前完成。对outputStream的写提交数据操作,必须要在inputStream的读操作之前。这些顺序实际上是由http请求的格式决定的。
       3.http请求实际上由两部分组成,一个是http头,所有关于此次http请求的配置都在http头里面定义,一个是正文content。connect()函数会根据HttpURLConnection对象的配置值生成http头部信息,因此在调用connect函数之前,就必须把所有的配置准备好。
      4.在http/https头后面紧跟着的是http/https请求的正文,正文的内容是通过outputStream流写入的, 实际上outputStream不是一个网络流,充其量是个字符串流,往里面写入的东西不会立即发送到网络,而是存在于内存缓冲区中(因此会有setUseCaches()这个方法),待outputStream流关闭时,根据输入的内容生成http正文。至此,http请求的东西已经全部准备就绪。在getInputStream()函数调用的时候,就会把准备好的http请求正式发送到服务器了,然后返回一个输入流,用于读取服务器对于此次http请求的返回信息。(来源于https://blog.csdn.net/yechaodechuntian/article/details/79976748)

2.对于https如何配置安全证书

https协议对于开发者而言其实只是多了一步证书验证的过程。这个证书正常情况下被jdk/jre/security/cacerts所管理。里面证书包含两种情况:

1、机构所颁发的被认证的证书,这种证书的网站在浏览器访问时https头显示为绿色如百度

2、个人所设定的证书,这种证书的网站在浏览器里https头显示为红色×,且需要点击信任该网站才能继续访问。而点击信任这一步的操作就是我们在java代码访问https网站时区别于http请求需要做的事情。
 

因此分两种情况:

第一种情况:Https网站的证书为机构所颁发的被认证的证书,这种情况下和http请求一模一样,无需做任何改变,用HttpsURLConnection或者HttpURLConnection都可以。

第二种情况:个人所设定的证书,这种证书默认不被信任,需要我们自己选择信任

    解决方案:本地设定证书 

  1.导入

import java.security.cert.X509Certificate;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.X509TrustManager;

2.重写证书管理

//证书管理
class MyX509TrustManager implements X509TrustManager {

    @Override
    public void checkClientTrusted(X509Certificate[] chain, String authType)
            throws CertificateException {
    }

    @Override
    public void checkServerTrusted(X509Certificate[] chain, String authType)
            throws CertificateException {
    }

    @Override
    public X509Certificate[] getAcceptedIssuers() {
        return null;
    }
}

3.初始化配置

SSLSocketFactory ssf=null;
try{
    //创建SSLContext
    SSLContext sslContext=SSLContext.getInstance("SSL");
    TrustManager[] tm={new MyX509TrustManager()};//信任管理
    //初始化
    sslContext.init(null, tm, new java.security.SecureRandom());
    //获取SSLSocketFactory对象
    ssf=sslContext.getSocketFactory();
}catch(Exception e){
    System.out.println("SSL配置出错");
    e.printStackTrace();
}

4.连接对象调用setSSLSocketFactory()方法

csdnConnection.setSSLSocketFactory(ssf);

3.demo

  1. import java.io.InputStreamReader;
    import java.net.*;
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    import java.util.ArrayList;
    import java.util.List;
    import javax.net.ssl.SSLSocketFactory;
    import javax.net.ssl.X509TrustManager;
    import javax.net.ssl.*;
    import javax.net.ssl.HttpsURLConnection;
    //实现https请求需要自定义SSL证书(https对链接使用安全证书SSL)
    public class Main {
        private static int COUNT=1000;//循环访问次数
        private static List<String> urls=new ArrayList<>();//网址
        private static int ERROR_COUNT=0;//访问出错总数
        //初始化信息
        static {
            urls.add("https://blog.csdn.net/qq_40918961/article/details/95912630");
            urls.add("https://blog.csdn.net/qq_40918961/article/details/99873716");
            urls.add("https://blog.csdn.net/qq_40918961/article/details/96607888");
            urls.add("https://blog.csdn.net/qq_40918961/article/details/96438282");
            urls.add("https://blog.csdn.net/qq_40918961/article/details/100144972");
        }
        public static void main(String[] args){
            //配置ssl管理
            SSLSocketFactory ssf=null;
            try{
                //创建SSLContext
                SSLContext sslContext=SSLContext.getInstance("SSL");
                TrustManager[] tm={new MyX509TrustManager()};//信任管理
                //初始化
                sslContext.init(null, tm, new java.security.SecureRandom());
                //获取SSLSocketFactory对象
                ssf=sslContext.getSocketFactory();
            }catch(Exception e){
                System.out.println("SSL配置出错");
                e.printStackTrace();
            }
    
            for(int i=0;i<COUNT;i++){
                for (String s:urls){
                    try {
                        if(s!=null){
                            URL csdn=new URL(s);//创建URl对象
                            HttpsURLConnection csdnConnection=(HttpsURLConnection) csdn.openConnection();//打开地址URL连接,使用https,设置请求对象格式与参数
                            //配置方法参数和请求属性
                            csdnConnection.setDoInput(true);
                            csdnConnection.setDoOutput(true);
                            csdnConnection.setUseCaches(false);
                            csdnConnection.setRequestMethod("GET");
                            csdnConnection.setSSLSocketFactory(ssf);
                            csdnConnection.setRequestProperty("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0");
                            csdnConnection.connect();//建立tcp连接
                            //发送请求并获得响应报文,返回流对象
                            InputStreamReader in;
                            if(csdnConnection.getResponseCode()==-1){
                                in=new InputStreamReader(csdnConnection.getErrorStream());
                            }else{
                                in=new InputStreamReader(csdnConnection.getInputStream());
                            }
                            in.close();//关闭数据流
                            csdnConnection.disconnect();//断开连接
                        }
                    }catch (Exception e){
                        ERROR_COUNT++;
                        e.printStackTrace();
                    }
                 }
                System.out.println("已执行"+(i+1)+"次");
                //防止频繁执行,睡眠30秒
                try{
                    Thread.currentThread().sleep(30000);
                }catch (Exception e){
                    System.out.println("睡眠失败");
                }
            }
            System.out.println("over,失败次数:"+ERROR_COUNT+"成功访问次数:"+(urls.size()*COUNT-ERROR_COUNT));
        }
    }
    
    //证书管理
    class MyX509TrustManager implements X509TrustManager {
    
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
        }
    
        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
        }
    
        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }
    }
    

4.总结

使用javax.net可以完成最基本的网络编程,总结一下:

1.构造一个URL对象

2.如果使用https,需要先配置安全访问证书,如ssl

3.通过在 URL 上调用 openConnection 方法创建连接对象,连接对象可以是HttpURLConnection或HttpsURLConnection,该链接对象相当于中间体,通过其配置http/https 访问信息参数。

4.配置连接对象(调用各种setter方法),即配置http/https 访问参数和请求属性

  如:            

            csdnConnection.setDoInput(true);
            csdnConnection.setDoOutput(true);//打开读取流
            csdnConnection.setUseCaches(false);//是否设置请求内容先放入缓冲区
            csdnConnection.setRequestMethod("GET");//设置请求参数
            csdnConnection.setRequestProperty("accept", "*/*");//设置通用的请求属性 更多的头字段信息可以查阅HTTP协议
            csdnConnection.setRequestProperty("connection", "Keep-Alive");

5.调用连接对象的connect方法建立tcp连接,此步只建立了tcp连接,并未发送请求

 6.调用连接对象的getInputStream()方法发送http请求,并获取响应数据。返回一个InputStream对象,即为所请求的http/https正文资源内容。

5.参考

https://blog.csdn.net/u010197591/article/details/51441399

https://blog.csdn.net/laiyaxing/article/details/51585755

6.补充

有时出现错误Server returned HTTP response code: 544 for URL:可能是过于频繁访问站点,DNS服务器误以为是Doos攻击所以将这个ip加入了黑名单,过一些时间就好了

猜你喜欢

转载自blog.csdn.net/qq_40918961/article/details/93628023