• Java 之网络编程


    网络模型

    1. OSI 模型, 把网络通信的工作分为七层.
    2. TCP/IP 模型, 把网络通信的工作分为四层
      • 应用层
      • 传输层
      • 网际层
      • 主机至网络层

    网络通信要素 (java.net 包)

    - IP 地址 (InetAddress)
    - 端口号
        - 用于标识进程的逻辑地址, 不同进程的标识
        - 有效端口: 0~65535, 其中 0~1024 为系统使用或保留端口
        - 2 的16次方 = 65536
    - 传输协议
        - 通讯的规则
        - 常见协议: TCP, UDP
    

    IP

    - java.net 包中, InetAddress 类
    - 网络模型中的网际层
    - 没有构造函数, 有非静态方法(单例设计模式)
    

    域名解析

    Socket

    - Socket 就是为网络服务提供的一种机制
    - 通信的两端都有 Socket
    - 网络通信其实就是 Socket 间的通信
    

    UDP

    1. 特点:
      • 将数据及源和目的封装到数据包中, 不需要建立连接
      • 每个数据包的大小限制在 64K 内
      • 因无连接, 是不可靠的协议
      • 不需要建立连接,速度快
      • 类似于生活中的对讲机
    2. 在 java 中的体现
      • DatagramSocket 用来发送和接收数据报包的 socket
      • DatagramPacket 表示数据报包
    // 需求一: 创建 UDP 传输的发送端
        /*
         * 思路:
         *    1. 建立 UDP 的 socket 服务
         *    2. 将要发送的数据封装到数据包中
         *    3. 通过 UDP 的 socket 服务将数据包发送出去
         *    4. 关闭 socket 服务
         */
    
         public static void main(String[] args) throws IOException {
    
            // 1. 创建 udp 的 socket 服务, 使用 DatagramSocket 对象
                DatagramSocket ds = new DatagramSocket();
    
            // 2. 将要发送的数据封装到数据包中
                String str = "udp传输演示:哥们来了!";
                // 使用 DatagramPacket 将数据封装到该对象包中
                byte[] buf = str.getBytes();
    
                DatagramPacket dp =new DatagramPacket(buf,
                                                      buf.length,
                                                      InetAddress.getByName("192.168.1.100"),
                                                      9999);  // 指定的为接收端的端口号
    
            // 3. 通过 udp 的 socket 服务将数据包发送出去, 使用 send 方法
                ds.send(dp);
    
            // 4. 关闭 socket 服务
                ds.close();
        }
    
    // 需求二: 创建 UDP 传输的接收端
        /*
         * 思路:
         *    1. 建立 udp 的 socket 服务, 因为是要接收数据, 必须要明确一个端口号
         *    2. 创建数据包, 用于存储接收到的数据, 方便用数据包对象的方法解析这些数据
         *    3. 使用 socket 服务的 receive 方法将接收的数据存储到数据包中
         *    4. 通过数据包的方法解析数据包中的数据
         *    5. 关闭资源
         * /
    
         public static void main(String[] args) throws IOException{
            // 1. 创建 socket 接收服务, 明确接收端口
                DatagramSocket ds = new DatagramSocket(9999);
    
            // 2. 创建数据包, 用于存储接收到的数据
                byte[] buf = new byte[1024];
                DatagramPacket dp = new DatagramPacket(buf,buf.length);
    
            // 3. 接收数据
                ds.receive(dp);
    
            // 4. 使用数据包对象的方法, 解析其中的数据, 比如地址, 端口, 数据内容
            String ip = dp.getAddress().getHostAddress();
            int port = dp.getPort();
            String text = new String(dp.getData(),0,dp.getLength());
    
            System.out.println(ip+"..."+port+"..."+text);
        }
    

    TCP

    -  建立连接,形成传输数据的通道
    -  在连接中进行大数据量传输
    -  通过三次握手完成连接,是可靠协议
    -  必须建立连接,效率会稍低
    -  类似生活中的手机
    
    // 需求一: 客户端发送数据到服务端
        /*
         * 思路:
         *     1. 创建 tcp 客户端 socket 服务. 使用的是 Socket 对象
         *        建议该对象一创建就明确目的地, 即指定要连接的主机
         *     2. 如果连接建立成功, 说明数据传输通道已建立
         *        该通道就是 socket 流, 是底层建立好的.
         *        既然是流,说明这里既有输入,又有输出.
         *        想要输入或者输出流对象, 可以找 socket 对象获取,而不能使用 new 创建
         *        可以通过 getOutputStream() 和 getInputStream() 来获取两个字节流
         *     3. 使用输出流, 将数据写出
         *     4. 关闭资源
         * /
    
         public static void main(String[] args){
    
            // 1. 创建客户端 socket 服务
                Socket socket =  new Socket("192.168.1.100",10001);
    
            // 2. 获取 socket 流中的输出流对象
                OutputStream out = socket.getOutputStream();
    
            // 3. 使用输出流将指定的数据写出去
                out.write("tcp演示: 哥们又来了!".getBytes());
    
            // 4. 关闭资源
                socket.close();
        }   
    
    // 需求二: 服务端接收客户端发送过来的数据, 并打印在控制台上
        /*
         * 思路:
         *    1. 创建服务端 socket 服务, 通过 ServerSocket 对象
         *    2. 服务端必须对外提供一个端口,否则客户端无法连接 (监听端口)
         *    3. 获取连接过来的客户端对象
         *    4. 通过客户端对象获取 socket 流读取客户端发来的数据, 并打印在控制台上
         *    5. 关闭资源. 包括客户端资源和服务端资源
         */
    
         public static void main(String[] args){
    
            // 1. 创建服务端对象
                ServerSocket ss = new ServerSocket(10001);
    
            // 2. 获取连接过来的客户端对象
                Socket s = ss.accept();
    
                String ip = s.getInetAddress().getHostAddress();
    
            // 通过 socket 对象获取输入流,并读取数据
                InputStream in = s.getInputStream();
    
                byte[] buf = new byte[1024];
    
                int len = in.read(buf);
                String text = new String(buf,0,len);
                System.out.println(ip+"..."+text);
    
            // 关闭资源
                s.close();
                ss.close();
        }
    

    // 需求三: 上传文本文档
    
        // TCP 客户端
        public static void main(String[] args) throws IOException{
    
            // 1. 创建客户端对象
            Socket s = new Socket("192.168.1.100", 10005);
    
            // 2. 文本文件与输入流关联
            BufferedReader bufr =
                        new BufferedReader(new FileReader("c:\client.txt"));
    
            // 3. 获取 socket 的输出流并装饰
            PrintWriter out = new PrintWriter(s.getOutputStream(),true);
    
            // 4. 将文件写入到输出流
            String line = null;
            while((line=bufr.readLine())!=null){
                out.println(line);
            }
    
            // 告诉服务端, 客户端写完了. 结束标记
            s.shutdownOutput();
    
            // 5. 读取服务端发来的数据
            BufferedReader bufrIn =
                            new BufferedReader(new InputStreamReader(s.getInputStream()));
    
            String str = bufrIn.readLine();
            System.out.println(str);
    
            // 6. 关闭资源
                bufr.close();
                s.close();
        }
    
        // TCP 服务端
        public static void main(String[] args) throws IOException{
    
            // 1. 创建服务端对象
                ServerSocket ss = new ServerSocket(10005);
    
            // 2. 获取客户端对象
                Socket s = ss.accept();
    
            // 3. 通过 socket 对象获取输入流
                BufferedReader bufrIn =
                            new BufferedReader(new InputStreamReader(s.getInputStream()));
    
            // 4. 服务端文件与输出流关联
                BufferedWriter bufw = new BufferedWriter(new FileWriter("c:\server.txt"));
    
            // 5. 从输入流中读取数据, 并写入到文件中
                String line = null;
                while((line=bufIn.readLine())!=null){
                    bufw.write(line);  
                    bufw.newLine();
                    bufw.flush(); // 写入一次后,需要刷新才能写入到文件中
                }
    
            // 6. 反馈给客户端信息
                PrintWriter out = new Printer(s.getOutputStream(),true);
    
                out.println("上传成功");
    
            // 7. 关闭资源
                bufw.close();
                s.close();
                ss.close();
        }
    

    **参考资料** - [JavaSE 基础视频(毕向东)](https://www.bilibili.com/video/av3133536/) - [JDK 1.6 中文文档](http://tool.oschina.net/apidocs/apidoc?api=jdk-zh) - [TCP的三次握手和四次挥手](http://blog.csdn.net/whuslei/article/details/6667471/)
  • 相关阅读:
    STS和Eclipse安装Lombok插件
    html5盒子模型
    SpringBoot整合Ribbon注入RestTemplate实例找不到原因
    Tomcat调整JVM大小,启动闪退
    quick cocos 设置屏幕大小
    quick cocos 多点触控,真机测试成功
    quick cocos 打包apk
    cocos3 多点触控 经过真机测试
    corona image sheet
    corona 杂类
  • 原文地址:https://www.cnblogs.com/linkworld/p/7522753.html
Copyright © 2020-2023  润新知