(备份)用socket 下载https网页



import java.io.*;
import javax.net.ssl.*;
import java.net.*;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;


/**
* @author lwh
* @date 2022/1/12
*/
public class Hs {
   public static String sentRequest(String path)  {
    
       try{
           //信任策略,我自己实现的策略,无需验证服务器的ssl证书
           TrustManager[] tm = {new NonValidationVerX509TrustManager()};
           //getInstance的第一个参数,具体查看https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#SSLContext
           SSLContext sslContext = SSLContext.getInstance("SSL");
           //第一个参数:密码仓库,我不需要验证证书,所以不需要,设置为空
           //第二个参数:信任策略,传我自己的
           //第三个参数:随机数
           sslContext.init(null, tm, new SecureRandom());
           //创建socket工厂
           SSLSocketFactory sc = sslContext.getSocketFactory();
           //创建访问的url
         
           Socket in=sc.createSocket(path,443);
           InputStream is=in.getInputStream();
           OutputStream os=in.getOutputStream();
           os.write("GET / HTTP/1.1\r\n".getBytes());
           os.write(("Host:"+path+"\r\n").getBytes());
           os.write("Connection:close\r\n\r\n".getBytes());
           os.flush();
           
           String s="";
           int k;
           k=is.read();
           while(k!=-1) {
        	   s=s+(char)k;
        	   k=is.read();
           }
           return s;
       } catch (MalformedURLException | NoSuchAlgorithmException | KeyManagementException e) {
           throw new RuntimeException("HttpsURLConnection 的SSL 配置异常"+e);
       } catch (IOException ioEx) {
           throw new RuntimeException("请求失败,原因:"+ ioEx);
       }
      
   }
   public static void main(String[] args)throws Exception{
       final String s1 = Hs.sentRequest("cn.bing.com");
       System.out.println(s1);
       File fl=new File("/home/wzpad/java/1.html");
       FileOutputStream os1=new FileOutputStream(fl);
       os1.write(s1.getBytes());
		
		
		
       
   }
 
   
   //请求类型 post/get
   public static enum HttpMethod{
       GET,POST;
   }


   public static class NonValidationVerX509TrustManager implements X509TrustManager {

       /**
        * 这里是服务器验证客户端证书的,这里不需要验证
        * @param chain 证书链,具体查看{@link X509TrustManager}
        * @param authType 基于客户端证书的认证类型 比如RSA,具体查看{@link X509TrustManager}
        * @throws CertificateException
        */
       @Override
       public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {

       }

       /**
        * 这里是客户端验证服务器证书的,这里不需要验证
        * @param chain 证书链,具体查看{@link X509TrustManager}
        * @param authType 使用的密钥交换算法,具体查看{@link X509TrustManager}
        * @throws CertificateException 证书验证失败,会抛出此异常
        */
       @Override
       public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
           System.out.println("不需要验证");
       }

       /**
        * 获取受信任的证书列表
        * @return 受信任的证书列表
        */
       @Override
       public X509Certificate[] getAcceptedIssuers() {
           return new X509Certificate[0];
       }
   }
}

我初学java   现在理解java.net.*包中,最重要的是几个类URL.  Socket. ServerSocket搞不好这几个类是c写的,没有见过源码.  剩下的类诂计可以用这几个类自己推出来。再学一下,看能不能用ssl协议写出客户端和服务器验证的过程,不用封装好的ssl类验证。

这种方法取得的网页文件是不能用于代理的,因为它通不过浏览器的验证。但这种文件下载到本地后再用浏览器是可以打开的,因为读本地的网页文件,浏览器不读首部就不进行验证了。

读http 和https网页的区别是后者多了ssl认证。认证后的所有操作都一样,客户端发首部请求后,服务器发响应首部,中间用\r\n隔开,发正文数据。我们可以根据服务器返回的首部,正文就可以写出属于自己的URLConnection 各种类和类方法。我们可以用两对\r\n来取出首部,用读文件完成的标志-1来取出正文。首部中又有各种属性,如length.  data.  accept.根据这些首部数据又可以写出类的各种方法。

学网络编程过程中,我感觉有一个地方特别有用,那就是在交互中怎样判断对方客户端,或者服务器已传输完文件或者命令。又怎样在不知道长度或者不知道完成标志的情况下写循环语句。所以,如果我以后写协议,一定会在完成语句加一条over, 还有,数组在这种不知道长度的情况下怎样使用。我现在用字符串,因为它可以变长度。好象java中有一个类stringbuilder,我理解就是一个字符串。

补充强调一下,一个socket就 可以输入输出编程,双向的,所以一个socket内的输入输出不能拆开分在两个socket中编程。所以也不能分在两个线程中了。这样理解,一个socket就是一条独路,一个通道,如果分开就是两条路了。那样输入输出就没有关联了。还有编客户端socket  必须是先向服务器请求,也就是先输出,再等待服务器的响应,再输入编程。不能反了。同理,服务器的socket必是先输入后相应客户端请求,再输出数据。这是客户端服务器输入输出的编程顺序。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值