前言: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
-
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加入了黑名单,过一些时间就好了