Http网络编程

一、Http 协议

介绍一下 Http 协议的特点

Http(Hyper text transfer protocal)超文本传输协议,属于应用层协议,用于客户端和服务器之间的数据通信。

有几个特点:

1)简单和快速

2)采用请求个响应的模式

3) 无连接(服务器将数据响应给客户端后,连接就断开了)

4)无状态(服务器不会保存客户端的信息)

Hppt 的请求方法

主要方法:

GET

获取信息

POST

增加信息

PUT

更新信息

DELETE

删除信息

TRACE

跟踪服务器状态

OPTIONS

获得服务器参数

HEAD

获得请求头部

CONNECT

用于连接

面试:GET 和 POST 的区别?

用途:GET 用于查询,POST 用于增加数据

传参方式:GET 放 URL,POST 放请求体里面

安全性:GET 参数直接可见,安全性低,POST 稍高

数据量:GET 受浏览器限制,2k 内,POST 没有限制

Http 的响应代码

响应码

说明

1xx

请求没有处理完

2xx

请求成功处理

3xx

请求重定向

4xx

客户端问题

5xx

服务器端问题

主要响应码:

  • 200 ok 成功
  • 400 参数错误
  • 401 没有通过登录验证
  • 403 没有访问权限
  • 404 资源不可用
  • 405 方法不对
  • 415 方法请求拒绝
  • 500 服务器错误
  • 503 服务器不可用

Http 的数据报文

http 的本质是使用 tcp 协议发送数据报文给服务器,服务器处理请求后,将响应数据和数据报文发给客户端。

请求报文

例子

响应报文

例子

Http 和 Https 的 区别

Http 是明文传输的,存在安全问题的;Https 是 Http 的安全版(s security),有 SSL 加密层, 数据以加密方式传输。

区别:

  • Https 以对称式和非对称式混合加密;Http 是明文
  • Https 需要在 CA 互联网机构购买证书;Http 不需要
  • Https 协议端口号默认是 443;Http 默认是 80

二、Http 编程

相关的一些 API:

  • URL 服务器资源
  • HttpURLConnection http 连接

URL 创建

new URL(服务器资源URL)

主要方法:

  • HttpConnection openConnection()

HttpURLConnection 主要方法

  • setConnectTimeout(连接超时)
  • setReadTimeout(读取超时)
  • setDoOutput(是否发送数据)
  • InputStream getInputStream() 获得输入流
  • OutputStream getOutputStream() 获得输出流
  • close() 关闭

文件下载

代码:

public class DownloadDemo {
    public static final String SAVE_PATH = "D:\\upload\\";

    /**
     * 文件下载
     *
     * @param urlStr
     */
    public void downLoad(String urlStr, String fileName) {
        try {
            // 创建URL对象
            URL url = new URL(urlStr);
            // 获得连接对象
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            //设置连接超时
            connection.setConnectTimeout(30000);
            // 判断正常连接
            if (connection.getResponseCode() == 200) {
                try (   // 获得输入流
                        InputStream inputStream = connection.getInputStream();
                        // 本地输出流
                        OutputStream outputStream = new FileOutputStream(SAVE_PATH + fileName);) {
                    // 定义缓冲区
                    byte[] buffer = new byte[1024];
                    // 每次读的长度
                    int len = 0;
                    //  循环读取数据,写入到本地文件
                    while ((len = inputStream.read(buffer)) != -1) {
                        outputStream.write(buffer, 0, len);
                    }
                    System.err.println("图片下载完成!!!");
                    Runtime.getRuntime().exec("mspaint " + SAVE_PATH + fileName);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        new DownloadDemo().downLoad("https://th.bing.com/th/id/R.8f26770f97928c922a9ea3256532f1a8?rik=%2flyrKGkLA4AGaA&riu=http%3a%2f%2fpic.zsucai.com%2ffiles%2f2013%2f0922%2fshu3.jpg&ehk=FB3Jpp94A%2bR%2fve7tvkv2tR3wvc8IxHMLYbes%2fkZEf38%3d&risl=&pid=ImgRaw&r=0", "mm.jpeg");
    }
}

三、Http 服务器原理

自定义 http 服务器

分析:

任务分解:

1) 创建ServerSocket,侦听8888端口

2) 循环获得客户端socket

3) 获得客户端的输入流,读取请求报文

问题:用什么流?字符流,BufferReader

4) 将报文中URL截取

5) 通过URL名称+html目录路径获得资源文件,读取其中的文字

问题: 封装读取文字的方法

6) 拼接响应报文,发送给浏览器

代码:

/**
 * 自定义Http服务器
 */
public class MyHttpServer {

    public static final int PORT = 999;
    public static final String HTML_DIR = "D:\\home";
    
    public void start(){
        System.out.println("启动服务器");
        //创建ServerSocket
        try(ServerSocket serverSocket = new ServerSocket(PORT)){
            while(true){
                //获得客户端连接
                Socket socket = serverSocket.accept();
                System.out.println("客户端连接:" + socket);
                //读取客户端的请求报文
                StringBuilder request = new StringBuilder();
                //读取请求报文
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                String line = null;
                while ((line = bufferedReader.readLine()) != null) {
                    request.append(line);
                    if (line.length() == 0) {//""
                        break;
                    }
                }
                System.out.println(request);
                //截取报文中的url
                int first = request.indexOf(" ");
                int second = request.indexOf(" ",first + 1);
                String url = request.substring(first + 1, second);
                System.out.println("url:" + url);
                File file = new File(HTML_DIR + url);
                StringBuilder stringBuilder = new StringBuilder();
                if(file.exists()){
                    //读取本地html文件
                    StringBuilder html = new StringBuilder();
                    try(BufferedReader reader = new BufferedReader(new FileReader(file))){
                        String s = null;
                        while((s = reader.readLine()) != null){
                            html.append(s + "\n");
                        }
                    }catch (IOException ex){
                        ex.printStackTrace();
                    }
                    System.out.println("html:" + html);
                    //拼接响应报文
                    stringBuilder.append("HTTP/1.1 200 OK\r\n");
                    stringBuilder.append("Content-Type: text/html; charset=UTF-8\r\n");
                    stringBuilder.append("Content-Length: " + html.toString().getBytes("UTF-8").length + "\r\n");
                    stringBuilder.append("\r\n");
                    stringBuilder.append(html);
                }else{
                    System.out.println("文件不存在" + file.getAbsolutePath());
                    stringBuilder.append("HTTP/1.1 404 NOT FOUND\r\n");
                }
                //发送响应报文给浏览器
                OutputStream outputStream = socket.getOutputStream();
                outputStream.write(stringBuilder.toString().getBytes());
                outputStream.flush();
                outputStream.close();
            }
        }catch (IOException ex){
            ex.printStackTrace();
        }
    }

    public static void main(String[] args) {
        new MyHttpServer().start();
    }
}

四、 JMeter

jJava开发的压力测试 QPS Query Per Second 每秒请求数 TPS Transaction Per Second 每秒事务量。

使用步骤:

1) 创建线程组

2) 设置线程数

3)设置HTTP请求


4) 设置请求接口信息

5) 添加监听器
 

6) 点击start启动测试

7)语言设置简体中文

8)启动 jmeter

自定义压力测试工具:

1) 输入线程数、IP、端口、请求方法、URL、参数、参数类型

2) 启动多个线程执行http请求

3) 显示每个线程返回响应数据以及执行时间

/**
 * 调用HTTP接口的案例
 */
public class HttpDemo {

    static String testGet(){
        try {
            URL url = new URL("http://localhost:8080/order-page?current=1&size=5");
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setConnectTimeout(3000);
            connection.setRequestMethod("GET");
            connection.connect();
            if(connection.getResponseCode() == 200){
                try(BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))){
                    String line = null;
                    StringBuilder stringBuilder = new StringBuilder();
                    while((line = reader.readLine()) != null){
                        stringBuilder.append(line + "\n");
                    }
                    return stringBuilder.toString();
                }catch (IOException ex){
                    ex.printStackTrace();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    static String testPost(){
        try {
            URL url = new URL("http://localhost:8080/order");
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setConnectTimeout(3000);
            connection.setRequestMethod("POST");
            //设置请求内容类型
            connection.addRequestProperty("Content-Type","application/json");
            //设置输出
            connection.setDoOutput(true);
            //发送参数
            String args = "{\"num\":1,\"goodsId\":1,\"userId\":1,\"time\":\"2020-11-11T11:11:11\"}";
            OutputStream outputStream = connection.getOutputStream();
            outputStream.write(args.getBytes("UTF-8"));
            outputStream.flush();
            connection.connect();
            if(connection.getResponseCode() == 200){
                try(BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))){
                    String line = null;
                    StringBuilder stringBuilder = new StringBuilder();
                    while((line = reader.readLine()) != null){
                        stringBuilder.append(line + "\n");
                    }
                    return stringBuilder.toString();
                }catch (IOException ex){
                    ex.printStackTrace();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        System.out.println(testPost());
        System.out.println(testGet());
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值