zoukankan      html  css  js  c++  java
  • 网络通信的要素

    网络通信的要素

    1. IP地址

    InetAddress

    • 唯一定位一台网络上的计算机

    • 127.0.0.1:本机 localhost

    • IP地址的分类

      • IPV4/IPV 6

        • IPV4:127.0.0.1 4个字节组成,0-255,42亿个;30亿都在北美,亚洲4亿

        • IPV6:128位。8个无符号整数(十六进制,abcde)

          2001:0bb2:aaaa:0015:0000:0000:1aaa:1312
          
      • 公网(互联网)-私网(局域网)

      • 192.168.XX.XX 专门给组织内部使用的

      • ABCD类地址

    • 域名:解决记忆IP问题

    2. Java中的InetAddress包

    package com.wang.lesson01;
    
    import java.net.InetAddress;
    import java.net.UnknownHostException;
    
    /**
     * @author wang
     * @creatTime 2020/8/7
     */
    //测试IP
    public class Test01 {
        public static void main(String[] args) {
            //快捷键 clt+alt+t
            try {
                //查询本机地址
                InetAddress inetAddress1 = InetAddress.getByName("127.0.0.1");
                System.out.println(inetAddress1);
                InetAddress inetAddress3 = InetAddress.getByName("localhost");
                System.out.println(inetAddress3);
                InetAddress inetAddress4 = InetAddress.getLocalHost();
                System.out.println(inetAddress4);
    
                //查询网站IP地址
                InetAddress inetAddress2 = InetAddress.getByName("www.baidu.com");
                System.out.println(inetAddress2);
    
                //常用方法
                //System.out.println(inetAddress2.getAddress());
                System.out.println(inetAddress2.getCanonicalHostName());    //规范的名字
                System.out.println(inetAddress2.getHostAddress());          //ip
                System.out.println(inetAddress2.getHostName());             //域名,或者本机的名字
    
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
        }
    }
    

    3. 端口

    端口表示计算机上的一个程序的进程

    • 不同的进程有不同的端口号!用来区分软件!

    • 被规定为0~65535

    • TCP,UDP:单个协议下,端口号不能冲突

    • 端口分类

      • 共有端口0~1023

        • HTTP:80
        • HTTPS:443
        • FTP:21
        • Telent:23
      • 程序注册端口:1024~49151,分配给用户或者程序

        • Tomcat:8080
        • MySQL:3306
        • Orale:1521
      • 动态、私有:49152~65535

      netstat -ano	#查看所有的端口
      netstat -ano|findstr "5900"	#查看指定的端口
      tasklist|findstr "8696"	#查看指定端口的进程
      Ctrl + Shift + Esc	#打开任务管理器
      
      package com.wang.lesson01;
      
      import java.net.InetSocketAddress;
      
      /**
       * @author wang
       * @creatTime 2020/8/7
       */
      public class TestIntSocketAddress {
          public static void main(String[] args) {
      
              InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1", 8080);
              System.out.println(inetSocketAddress.toString());
              InetSocketAddress inetSocketAddress2 = new InetSocketAddress("localhost", 8080);
              System.out.println(inetSocketAddress2.toString());
      
              System.out.println(inetSocketAddress.getAddress());
              System.out.println(inetSocketAddress.getHostName());    //地址
              System.out.println(inetSocketAddress.getPort());        //端口
          }
      }
      

    4. 通信协议

    协议:约定

    网络通信协议:速率,传输码率,代码结构,传输控制

    问题:复杂

    解决方法:大事化小---->分层

    TCP/IP协议簇:实际上是一种协议

    重要

    • TCP:用户传输协议
    • UDP:用户数据报协议

    出名的协议

    • TCP
    • IP:网络互连协议

    TCP UDP对比

    TCP:打电话

    • 连接,稳定
    • 三次握手,四次挥手
    • 客户端,服务端
    • 传输完成,释放连接,效率低

    UDP:发短信

    • 不连接,不稳定
    • 客户端,服务端:没有明确的界限
    • 不管有没有准备好,都可以发给你
    • 类比:导弹
    • DDOS:饱和攻击

    5. TCP

    1. 客户端

    1. 连接服务器Socket
    2. 发送消息
    package com.wang.lesson02;
    
    import java.io.IOException;
    import java.io.OutputStream;
    import java.net.InetAddress;
    import java.net.Socket;
    
    /**
     * @author wang
     * @creatTime 2020/8/7
     */
    //客户端
    public class TCPClientDemo01 {
        public static void main(String[] args) {
            Socket socket = null;
            OutputStream os = null;
            try {
                //1.要知道服务器的地址
                InetAddress serverIP = InetAddress.getByName("127.0.0.1");
                //2. 端口号
                int port = 9999;
                //3. 创建一个socket连接
                socket = new Socket(serverIP, port);
                //4. 发送消息IO流
                os = socket.getOutputStream();
                os.write("这是一行字".getBytes());
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (socket != null){
                    try {
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
    
                if (os != null){
                    try {
                        os.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    

    2. 服务器

    1. 建立服务端的端口
    2. 等待用户的连接accept(),返回客户的socket
    3. 接收用户的消息
    package com.wang.lesson02;
    
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    /**
     * @author wang
     * @creatTime 2020/8/7
     */
    //服务端
    public class TCPServerDemo01 {
        public static void main(String[] args) {
            ServerSocket serverSocket = null;
            Socket socket = null;
            InputStream is = null;
            ByteArrayOutputStream baos = null;
            try {
                //1. 我得有一个地址
                serverSocket = new ServerSocket(9999);
                //2. 等待客户端连接过来
                socket = serverSocket.accept();
                //3. 读取客户端的消息
                is = socket.getInputStream();
                //管道流
                baos = new ByteArrayOutputStream();
                byte[] buffer = new byte[1024];
                int len;
                while ((len = is.read(buffer)) != -1) {
                    baos.write(buffer,0,len);
                }
    
                System.out.println(baos.toString());
    
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                //关闭资源
                if (baos != null){
                    try {
                        baos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
    
                if (is != null){
                    try {
                        is.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
    
                if (socket != null){
                    try {
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
    
                if (serverSocket != null){
                    try {
                        serverSocket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
    
        }
    }
    

    3. 文件上传

    服务器端

    package com.wang.lesson02;
    
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.nio.file.Files;
    import java.nio.file.NoSuchFileException;
    import java.nio.file.Paths;
    
    /**
     * @author wang
     * @creatTime 2020/8/7
     */
    public class TCPServerDemo02 {
        public static void main(String[] args) throws Exception{
            //1.创建服务
            ServerSocket serverSocket = new ServerSocket(9999);
            //2.监听客户端的连接
            Socket socket = serverSocket.accept();//阻塞式监听,会一直等待客户端连接
            //3.获取输入流
            InputStream is = socket.getInputStream();
    
            //4.文件输出,由于同名的文件存在时会抛出异常,因此先删除同名文件
            try{
                Files.delete(Paths.get("pic_receive.jpg"));
                Files.copy(is, Paths.get("pic_receive.jpg"));
            } catch (NoSuchFileException e) {
                //如果同名文件不存在,则在NoSuchFileException中直接复制
                Files.copy(is, Paths.get("pic_receive.jpg"));
            }
    
            //通知客户端我接收完毕了
            OutputStream os = socket.getOutputStream();
            os.write("我接收完毕了,你可以断开了".getBytes());
    
            is.close();
            socket.close();
            serverSocket.close();
        }
    }
    
    

    客户端

    package com.wang.lesson02;
    
    import java.io.ByteArrayOutputStream;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.InetAddress;
    import java.net.Socket;
    import java.nio.file.Files;
    import java.nio.file.Path;
    import java.nio.file.Paths;
    
    /**
     * @author wang
     * @creatTime 2020/8/7
     */
    public class TCPClientDemo02 {
        public static void main(String[] args) throws Exception{
            //1. 创建一个socket连接
            Socket socket = new Socket(InetAddress.getByName("localhost"), 9999);
            //2. 创建一个输出流
            OutputStream os = socket.getOutputStream();
    
            //文件流 Files用copy写到输入输出流,用readAllXXX读进来
            //3. 读取文件
            Path filePath = Paths.get("pic.jpg");
    
            //4. 写出文件
            Files.copy(filePath, os);
    
            //通知服务器,我已经结束了
            socket.shutdownOutput();    //我已经传输完了
    
            //确定服务器接收完毕,才能断开连接
            InputStream inputStream = socket.getInputStream();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
    
            byte[] buffer = new byte[1024];
            int len;
            while ((len = inputStream.read(buffer)) != -1){
                baos.write(buffer,0,len);
            }
    
            System.out.println(baos.toString());
    
            //5.关闭资源
            baos.close();
            inputStream.close();
            os.close();
            socket.close();
        }
    }
    
    

    6. Tomcat

    服务端

    • 自定义 S
    • Tomcat S:Java后台开发

    客户端

    • 自定义 C
    • 浏览器 B

    7. UDP

    发短信:不用连接,需要知道对方的地址!

    1. UDP实现发送消息

    package com.wang.lesson03;
    
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    
    /**
     * @author wang
     * @creatTime 2020/8/10
     */
    
    //不需要连接服务器
    public class UDPClientDemo01 {
        public static void main(String[] args) throws Exception {
            //1.建立一个socket
            DatagramSocket socket = new DatagramSocket();
    
            //2.建个包
            String msg = "Hello, Server!";
    
            //发送给谁
            InetAddress localhost = InetAddress.getByName("localhost");
            int port = 9090;
    
            //数据,数据的长度起始,要发送给谁
            DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, localhost, port);
    
            //3.发送包
            socket.send(packet);
    
            //4.关闭流
            socket.close();
        }
    }
    

    UDP实现接收消息

    package com.wang.lesson03;
    
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    
    /**
     * @author wang
     * @creatTime 2020/8/10
     */
    //还要等待客户端的连接
    public class UDPServerDemo01 {
        public static void main(String[] args) throws Exception {
            //开放端口
            DatagramSocket socket = new DatagramSocket(9090);
            //接收数据包
            byte[] buffer = new byte[1024];
            DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
    
            socket.receive(packet); //阻塞接收
    
            //关闭连接
            socket.close();
    
            //public String(byte[] bytes,int index,int length) 把字节数组的一部分转成字符串
            System.out.println(new String(packet.getData(), 0, packet.getData().length));
        }
    }
    

    2. 咨询

    循环发送消息

    package com.wang.chat;
    
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetSocketAddress;
    
    /**
     * @author wang
     * @creatTime 2020/8/10
     */
    public class UDPSenderDemo01 {
        public static void main(String[] args) throws Exception {
            DatagramSocket socket = new DatagramSocket(8888);
    
            //准备数据:控制台读取System.in
            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
            while (true) {
                String data = reader.readLine();
                byte[] dataBytes = data.getBytes();
    
                DatagramPacket packet = new DatagramPacket(dataBytes, 0, dataBytes.length, new InetSocketAddress("localhost", 6666));
    
                socket.send(packet);
    
                if (data.equals("bye"))
                    break;
            }
    
            socket.close();
    
        }
    }
    

    循环接收消息

    package com.wang.chat;
    
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    
    /**
     * @author wang
     * @creatTime 2020/8/10
     */
    public class UDPReceiveDemo01 {
        public static void main(String[] args) throws Exception {
            DatagramSocket socket = new DatagramSocket(6666);
    
            while (true) {
                //准备接收包裹
                byte[] container = new byte[1024];
                DatagramPacket packet = new DatagramPacket(container, 0, container.length);
    
                socket.receive(packet); //阻塞式接收包裹
    
                //当接收到"bye",断开连接
                byte[] data = packet.getData();
                String receiveData = new String(data, 0, data.length);
                System.out.println(receiveData);
                if (receiveData.equals("bye"))
                    break;
            }
    
            socket.close();
        }
    }
    

    3. 在线咨询

    两个人都可以是发送方,也都可以是接收方:使用多线程

    循环发送消息

    package com.wang.chat;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetSocketAddress;
    
    /**
     * @author wang
     * @creatTime 2020/8/10
     */
    public class TalkSend implements Runnable {
    
        DatagramSocket socket = null;
        BufferedReader reader = null;
    
        private int fromPort;
        private String toIP;
        private int toPort;
    
        public TalkSend(int fromPort, String toIP, int toPort) {
            this.fromPort = fromPort;
            this.toIP = toIP;
            this.toPort = toPort;
    
            try {
                socket = new DatagramSocket(fromPort);
                reader = new BufferedReader(new InputStreamReader(System.in));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void run() {
    
            //准备数据:控制台读取System.in
            while (true) {
                try {
                    String data = reader.readLine();
                    byte[] dataBytes = data.getBytes();
    
                    DatagramPacket packet = new DatagramPacket(dataBytes, 0, dataBytes.length, new InetSocketAddress(this.toIP, this.toPort));
    
                    socket.send(packet);
    
                    if (data.equals("bye"))
                        break;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    
            socket.close();
    
        }
    }
    

    循环接收消息

    package com.wang.chat;
    
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.SocketException;
    
    /**
     * @author wang
     * @creatTime 2020/8/10
     */
    public class TalkReceive implements Runnable {
        DatagramSocket socket = null;
        private int port;
        private String msgFrom;
    
        public TalkReceive(int port, String msgFrom) {
            this.port = port;
            this.msgFrom = msgFrom;
            try {
                socket = new DatagramSocket(port);
            } catch (SocketException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void run() {
            try {
                while (true) {
                    //准备接收包裹
                    byte[] container = new byte[1024];
                    DatagramPacket packet = new DatagramPacket(container, 0, container.length);
    
                    socket.receive(packet); //阻塞式接收包裹
    
                    //当接收到"bye",断开连接
                    byte[] data = packet.getData();
                    String receiveData = new String(data, 0, data.length);
                    System.out.println(msgFrom + ":" + receiveData);
                    if (receiveData.equals("bye"))
                        break;
    
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            socket.close();
        }
    }
    

    老师端

    package com.wang.chat;
    
    /**
     * @author wang
     * @creatTime 2020/8/10
     */
    public class TalkTeacher {
        public static void main(String[] args) {
            //开启两个线程
            new Thread(new TalkSend(5555, "localhost", 8888)).start();
            new Thread(new TalkReceive(9999, "学生")).start();
        }
    }
    

    学生端

    package com.wang.chat;
    
    /**
     * @author wang
     * @creatTime 2020/8/10
     */
    public class TalkStudent {
        public static void main(String[] args) {
            //开启两个线程
            new Thread(new TalkSend(7777, "localhost", 9999)).start();
            new Thread(new TalkReceive(8888, "老师")).start();
        }
    }
    

    8. URL

    统一资源定位符:定位互联网上的某一个资源

    DNS域名解析:www.baidu.com ===> XXX.XX.XX.X

    组成:

    协议://ip地址:端口/项目名/资源

    可以少但是不能多

    package com.wang.lesson04;
    
    import java.net.MalformedURLException;
    import java.net.URL;
    
    /**
     * @author wang
     * @creatTime 2020/8/10
     */
    public class URLDemo01 {
        public static void main(String[] args) throws MalformedURLException {
            URL url = new URL("http://localhost:8080/helloworld/index.jsp?username=wang&password=123");
            System.out.println(url.getProtocol());      //协议
            System.out.println(url.getHost());          //主机ip
            System.out.println(url.getPort());          //端口
            System.out.println(url.getPath());          //文件
            System.out.println(url.getFile());          //全路径
            System.out.println(url.getQuery());         //参数
        }
    }
    

    利用URL下载文件

    package com.wang.lesson04;
    
    import java.io.InputStream;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.nio.file.Files;
    import java.nio.file.NoSuchFileException;
    import java.nio.file.Path;
    import java.nio.file.Paths;
    
    /**
     * @author wang
     * @creatTime 2020/8/10
     */
    public class URLDown {
        public static void main(String[] args) throws Exception {
            //1.下载地址
            URL url = new URL("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1597050462137&di=e81d42b6c04eeff13b8011bdcdb7b5e7&imgtype=0&src=http%3A%2F%2Ft8.baidu.com%2Fit%2Fu%3D1484500186%2C1503043093%26fm%3D79%26app%3D86%26f%3DJPEG%3Fw%3D1280%26h%3D853");
    
            //2.连接到这个资源 用Http
            HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
    
            InputStream inputStream = urlConnection.getInputStream();
    
            //利用Path和Files简化文件的IO
            String filePath = "download_pic.jpg";
            Path path = Paths.get(filePath);
            //考虑到可能存在同名文件,先删除同名文件,再copy
            try {
                Files.delete(path);
                Files.copy(inputStream, path);
            } catch (NoSuchFileException e) {
                //不存在同名文件,会抛出NoSuchFileException,此时直接copy
                Files.copy(inputStream, path);
            }
    
            inputStream.close();
        }
    }
    
  • 相关阅读:
    【微信小程序】数组操作
    iOS中html打开APP传参
    给radio加自己的样式(图片)
    TCP和IP的三次握手和第四次挥手
    什么是HTTP协议
    http和https的区别
    微信小程序-点击图片预览
    JAVASE
    thinkphp自学笔记
    前端必须掌握的30个CSS选择器
  • 原文地址:https://www.cnblogs.com/wang-sky/p/13469832.html
Copyright © 2011-2022 走看看