• Java网络编程


    http协议

    HTTP协议的版本

      HTTP/1.0、HTTP/1.1
    区别:
      1.0:每次响应后即刻关闭了连接。客户端与web服务器建立连接后,只能获得一个web资源。
      1.1:不是每次响应后挂断,等待长时间以后没有请求会挂断。允许客户端与web服务器建立连接后,在一个连接上获取多个web资源。

    请求部分

    请求行
      提交方式
        提交方式有很多,常用的GET和POST;
          GET和POST的区别:
            GET的提交的参数会显示到地址栏上,而POST不显示.
            GET往往是有大小限制的,而POST没有大小的限制.
            GET没有请求体,而POST有请求体.
      提交路径
      协议版本

    请求头
      都是键值对的形式显示的.一般一个key对应一个value,也有个别的是一个key对应多个value。
      HTTP请求中的常用消息头:
      User-Agent:代表浏览器的类型。 --文件下载:下载中文文件,IE使用URLEncodor进行编码,而Firefox使用Base64编码。
      accept:浏览器通过这个头告诉服务器,它所支持的数据类型
      Accept-Charset: 浏览器通过这个头告诉服务器,它支持哪种字符集
      Accept-Encoding:浏览器通过这个头告诉服务器,支持的压缩格式
      Accept-Language:浏览器通过这个头告诉服务器,它的语言环境
      Host:浏览器通过这个头告诉服务器,想访问哪台主机
      If-Modified-Since: 浏览器通过这个头告诉服务器,缓存数据的时间
      Referer:浏览器通过这个头告诉服务器,客户机是哪个页面来的  防盗链
      Connection:浏览器通过这个头告诉服务器,请求完后是断开链接还是何持链接存

    请求体
      就是POST提交方式的提交的参数

    响应部分

    响应行
      协议版本
      状态码:
        200  成功
        302  重定向
        304  查找本地缓存
        404  资源不存在
        500  服务器内部错误
      状态码描述

    响应头:键值对,一般一个key对应一个value,也有一个key对应多个value。
      HTTP响应中的常用响应头(消息头)
      Location:服务器通过这个头,来告诉浏览器跳到哪里
      Server:服务器通过这个头,告诉浏览器服务器的型号
      Content-Encoding:服务器通过这个头,告诉浏览器,数据的压缩格式
      Content-Length: 服务器通过这个头,告诉浏览器回送数据的长度
      Content-Language: 服务器通过这个头,告诉浏览器语言环境
      Content-Type:服务器通过这个头,告诉浏览器回送数据的类型
      Refresh:服务器通过这个头,告诉浏览器定时刷新
      Content-Disposition: 服务器通过这个头,告诉浏览器以下载方式打数据
      Transfer-Encoding:服务器通过这个头,告诉浏览器数据是以分块方式回送的
      Expires: -1  控制浏览器不要缓存
      Cache-Control: no-cache  
      Pragma: no-cache

    响应体:显示浏览器的页面的内容。

    在服务端设置响应头来控制客户端浏览器的行为

    设置Location响应头,实现请求重定向

    response.setStatus(302);//设置服务器的响应状态码

    response.setHeader("Location", "/demo5-refresh/success.html ");

    设置content-type响应头,指定回送数据类型

    String type = this.getServletContext().getMimeType(filename);

    response.setHeader("Content-Type", type);

    设置refresh响应头,让浏览器定时刷新

    response.setHeader("refresh", "3;url='http://www.baidu.com'");

    设置content-disposition响应头,让浏览器下载文件

    response.setHeader("content-disposition", "attachment;filename=xxx.jpg");


    网络编程

    InetAdderss类,该类用于封装一个IP地址,并提供了一系列与IP地址相关的方法。

    UDP 用户数据报协议

    DatagramPacket类,该类的实例对象就相当于一个集装箱,用于封装UDP通信中发送或者接收的数据。

    接收端的构造方法只需要接收一个字节数组来存放接收到的数据,而发送端的构造方法不但要接收存放了发送数据的字节数组,还需要指定发送端IP地址和端口号。

    DatagramPacket(byte[] buf, int length)  构造 DatagramPacket,用来接收长度为 length 的数据包。
    DatagramPacket(byte[] buf, int length, InetAddress address, int port)  构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。

    DatagramSocket类的作用就类似于码头,使用这个类的实例对象就可以发送和接收DatagramPacket数据包。

    在创建发送端和接收端的DatagramSocket对象时,使用的构造方法也有所不同。

    DatagramSocket()  构造数据报套接字并将其绑定到本地主机上任何可用的端口。
    DatagramSocket(int port)  创建数据报套接字并将其绑定到本地主机上的指定端口。

    package com.boomoom;
    
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    import java.net.SocketException;
    
    /*
     * 使用UDP协议发送数据
     */
    public class SendDemo {
        public static void main(String[] args) throws IOException  {
            //创建发送端Socket对象
            DatagramSocket ds = new DatagramSocket();
    
            //创建数据并打包        
            String s = "hello body, im a coder!";
            byte[] bys = s.getBytes();
            int length = bys.length;
            InetAddress address = InetAddress.getByName("boomoom");//发送给当前设备
            int port = 8888;
            DatagramPacket dp = new DatagramPacket(bys,length,address,port);
            ds.send(dp);
            ds.close();
        }
    }
    
    
    package com.boomoom;
    
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    
    /*
     * 使用UDP协议接收数据
     */
    public class ReceiveDemo {
        public static void main(String[] args) throws IOException {
            //创建接收端Socket对象
            DatagramSocket ds = new DatagramSocket(8888);
            //接收数据
            //DatagramPacket(byte[] buf, int length) 
            byte[] bys = new byte[1024];
            DatagramPacket dp = new DatagramPacket(bys,bys.length);
                    
            System.out.println(1);
            ds.receive(dp);//阻塞
            System.out.println(2);
            
            //解析数据
            InetAddress address = dp.getAddress(); // 获取发送端的IP对象
            int length = dp.getLength();
            
            System.out.println("sender ---> " + address.getHostAddress());
            System.out.println(new String(bys,0,length));
            ds.close();
        }
    }
    使用UDP协议发送接收数据

    TCP 传输控制协议

    UDP 中只有发送端和接收端,不区分客户端与服务器端,计算机之间可以任意地发送数据。而 TCP 通信是严格区分客户端与服务器端的,在通信时,必须先由客户端去连接服务器端才能实现通信,服务器端不可以主动连接客户端,并且服务器端程序需要事先启动,等待客户端的连接。在 JDK 中提供了两个类用于实现 TCP 程序,一个是 ServerSocket 类,用于表示服务器端,一个是 Socket 类,用于表示客户端。

    ServerSocket类,的实例对象可以实现一个服务器端的程序。

    Socket类,用于实现TCP客户端程序。

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.net.Socket;
    
    public class ClientTest {
        public static void main(String[] args) throws  IOException  {
            //创建客户端Socket对象
            Socket s = new Socket("janden-pc",8888);
    
            //获取用户名和密码
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("请输入用户名:");
            String username = br.readLine();
            System.out.println("请输入密码:");
            String password = br.readLine();
    
    
            //获取输出流对象
            PrintWriter out = new PrintWriter(s.getOutputStream(),true);
            //写出数据
            out.println(username);
            out.println(password);
    
            //获取输入流对象
            BufferedReader serverBr = new BufferedReader(new InputStreamReader(s.getInputStream()));
            //获取服务器返回的数据
            String result = serverBr.readLine();
            System.out.println(result);
            //释放资源
            s.close();
        }
    }
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.List;
    
    public class ServerTest {
        public static void main(String[] args) throws IOException {
            //创建服务器端Socket对象
            ServerSocket ss = new ServerSocket(8888);
            //监听
            Socket s = ss.accept();
            //获取输入流对象
            BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
            String username = br.readLine();
            String password = br.readLine();
    
            boolean flag = false;
            List<User> users = UserDB.getUsers();
            User user = new User(username,password);
            if(users.contains(user)) {
                flag = true;
            }
    
            //获取输出流对象
            PrintWriter out = new PrintWriter(s.getOutputStream(),true);
    
            //返回判断信息
            if(flag) {
                out.println("登陆成功");
            }
            else {
                out.println("登陆失败");
            }
            //释放资源
            s.close();
            //ss.close();//服务器一般不关闭
        }
    }
    
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class UserDB {
        private static List<User> users = new ArrayList<User>();
        
        static {
            users.add(new User("张三","123"));
            users.add(new User("赵四","1234"));
            users.add(new User("阿Q","12345"));
            users.add(new User("尼古拉斯","123456")); 
        }
    
        public static List<User> getUsers() {
            return users;
        }
    }
    
    import java.util.Objects;
    
    public class User {
        private String username;
        private String password;
    
        public User() {
            super();
        }
    
        public User(String username, String password) {
            this.username = username;
            this.password = password;
        }
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            User user = (User) o;
            return Objects.equals(username, user.username) &&
                    Objects.equals(password, user.password);
        }
    }
    使用TCP协议收发数据

    在应用层写入的数据经由表示层格式化编码,再由会话层标记发送顺序后才被发送出去。
    会话层只对何时建立连接、何时发送数据等问题进行管理。
    传输层建立连接或断开连接,创建逻辑上的通信连接。为保证数据传输的可靠性,它会在通信两端之间进行确认,并负责重发。
    网络层将数据传输给对端。
    数据链路层的作用是还在传输介质互联的设备间进行数据处理。
    物理层将数据转为电压或脉冲光传输给物理的传输介质。

    发一封邮件为例
    应用层的首部 标明收件人邮件主题内容。
    表示层的首部 编码格式识别信息。
    会话层的首部 记录数据传送顺序。
    传输层的首部 用以识别传输层。
    网络层的首部 两端IP地址、协议等。
    数据链路层的首部 帧定界符合长度上限。
    物理层的首部 含有MAC地址。

  • 相关阅读:
    js 时间相关函数
    javascript面向对象:继承、多态
    面向对象相关
    reset.css css重置公共样式
    开通博客园第一天。
    vue 和 react 路由跳转和传参
    前端密码加密方式
    react组件回顶部
    移动端使用rem方法
    用rekit创建react项目
  • 原文地址:https://www.cnblogs.com/boomoom/p/10312184.html
Copyright © 2020-2023  润新知