1 Star 0 Fork 165

ElonChung / Java-Review

forked from flatfish / Java-Review 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
java-网络编程-基础.md 15.60 KB
一键复制 编辑 原始数据 按行查看 历史
icanci 提交于 2020-09-07 23:09 . :fire:更新文件夹

网络编程

概述

地球村:你在一个地方,但是在另外一个地方

计算机网络

计算机网络是指将 地理位置不同的具有的独立功能的多台计算机以及其外部设备,通过通信线路连接起来,在因特网操作系统,网络管理软件以及网络通信协议的管理和协调下,实现资源共享和信息传递的计算系统

网络编程的目的

  • 电台:传播交流信息 数据交换 通信

想要达到这个效果需要什么

  • 如何准确定位网络上的主机:电脑的ip地址:端口 定位到这个计算机上的某个资源
  • 找到了这个主机,如何传输数据呢?

JavaWeb开发:网页编程 B/S

网络编程 TCP/IP:C/S

网络通信的要素

人工智能:智能化汽车

如何实现网络的通信:

  • 通信双方的地址
    • ip
    • 端口
  • 规则:网络通信的协议
    • http、udp、ftp
    • TCP/IP参考模型
  • 小结
    • 网络编程中有两个注意的问题
      • 如何准确的定位到网络上的一台或者多台主机
      • 找到主机之后如何通信
    • 网络编程中的要素
      • IP和端口号
      • 网络通信协议
    • 万物皆对象

ip地址

ip地址:InetAddress

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

  • 127.0.0.1:本机地址 等价于 localhost

  • ip地址的分类

    • ip地址的分类
      • IPV4 127.0.0.1 4个字节组成 0 ~ 255 42亿 。
      • IPV6 fe80::e00a:a009:e9a1:d0e4%17 128 位。8个无符号整数
    • 公网(互联网)- 私网
      • 192.168.xx.xx 专门给内部组实使用问题
  • 域名:记忆IP问题

    • ip: ip地址很不好记忆,所以就有了域名绑定ip地址
  • public class TestInetAddress {
        public static void main(String[] args) {
            try {
                // 查询网络地址
                InetAddress byName = InetAddress.getByName("www.baidu.com");
                InetAddress localHost = InetAddress.getLocalHost();
                System.out.println(localHost);
                System.out.println(byName);
    
                // 常用的方法
                System.out.println(byName.getHostName());
                System.out.println(byName.getAddress());
                // 规范的名字
                System.out.println(byName.getCanonicalHostName());
                System.out.println(byName.getHostAddress());
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
        }
    }

端口

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

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

  • 被规定到 0~65535

  • TCP和UDP:加在一起就是 65535 * 2,单个写一下端口号不能冲突

  • 端口分类

    • 共有端口 0~1023

      • HTTP:80
      • HTTPS:443
      • FTP:21
      • Telent:23
    • 程序注册端口:1024~49151

      • Tocat:8080
      • MySQL:3306
      • Redis:6379
    • 动态端口、私有端口:49152~65535

      netstat -ano # 查看所有的端口
      netstat -ano |findstr "5900" # 查询某个端口
      tasklist|findstr "5464" # 查看指定端口的进程
      public class TestInetSocketAddress {
          public static void main(String[] args) {
              InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1", 8080);
              System.out.println(inetSocketAddress);
              System.out.println(inetSocketAddress.getAddress());
              System.out.println(inetSocketAddress.getHostName());
          }
      }

通信协议

协议:约定,就是现在说的普通话

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

大事化小:分层

TCP/IP 协议簇,实际上是一组协议

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

出名协议:

  • TCP:
  • IP:协议

TCP和UDP对比

TCP:打电话

  • 连接、稳定

  • 三次握手 四次挥手

    • 最少三次才能保证连接
      A:你瞅啥?
      B:瞅你咋地?
      A:来,干你
      
      A:我要断开了
      B:我知道你要断开了
      B:你真的断开了?
      A:我真的断开了
  • 客户端、服务端

  • 传输完成,就会释放连接

UDP:发短信

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

TCP协议

客户端

  • 连接服务器Socket
  • 发送消息

服务器

  • 建立服务的接口 ServerSocket
  • 等待用户的连接 accept
  • 接收用户的信息
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 = 10000;
            //3. 创建一个Socket连接
            socket = new Socket(serverIp, port);
            //4. 发送消息
            os = socket.getOutputStream();
            os.write("hello,小猪童鞋".getBytes());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                socket.close();
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}
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(10000);
            while (true) {
                //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 {
            try {
                baos.close();
                is.close();
                socket.close();
                serverSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

文件上传

服务器端

public class TcpServerDemo02 {
    public static void main(String[] args) throws Exception {
        //1.创建服务
        ServerSocket serverSocket = new ServerSocket(10000);
        //2.监听客户端的连接
        // 阻塞式监听,会一直监听客户端的请求连接
        Socket socket = serverSocket.accept();
        //3.获取输入流
        InputStream is = socket.getInputStream();
        //4.文件输出
        FileOutputStream fos = new FileOutputStream(new File("res.doc"));
        byte[] buffer = new byte[1024];
        int len;
        while ((len = is.read(buffer)) != -1) {
            fos.write(buffer, 0, len);
        }
        // 通知服务端接收完毕
        OutputStream os = socket.getOutputStream();
        os.write("我接收完毕了,你可以断开了".getBytes());

        //5.关闭资源
        fos.close();
        is.close();
        socket.close();
        serverSocket.close();
    }
}

客户端

public class TcpClientDemo02 {
    public static void main(String[] args) throws Exception {
        //1. 创建一个Socket连接
        Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 10000);
        //2. 创建一个输出流
        OutputStream os = socket.getOutputStream();
        //3. 文件流 读取文件
        FileInputStream fis = new FileInputStream(new File("ic.doc"));
        //4. 写出文件
        byte[] buffer = new byte[1024];
        int len;
        while ((len = fis.read(buffer)) != -1) {
            os.write(buffer, 0, len);
        }
        // 通知服务器,我已经接收完毕
        // 我已经传输完了
        socket.shutdownOutput();

        // 确定服务端接收完毕,才能断开连接
        InputStream inputStream = socket.getInputStream();
        // String 类型的数组
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] bytes = new byte[1024];
        int len2;
        while ((len2 = inputStream.read(bytes)) != -1) {
            baos.write(bytes, 0, len2);
        }
        System.out.println(baos.toString());
        //5. 关闭资源
        baos.close();
        inputStream.close();
        fis.close();
        os.close();
        socket.close();
    }
}

Tomcat

服务端

  • 自定义 S
  • Tomcat 服务器 S

客户端

  • 自定义C
  • 浏览器B

UDP

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

发送消息

public class UdpClientDemo01 {
    public static void main(String[] args) throws Exception {
        //1. 建立一个Socket
        DatagramSocket socket = new DatagramSocket();
        //2. 建个包
        String message = "你好,服务器";
        // 发送给谁
        InetAddress localhost = InetAddress.getByName("localhost");
        int port = 10000;
        // 数据 数据的开始位置 数据的长度 主机地址 主机端口号地址
        DatagramPacket datagramPacket = new DatagramPacket(
                message.getBytes(),
                0,
                message.getBytes().length,
                localhost,
                port
        );
        //3. 发送包
        socket.send(datagramPacket);

        //4. 关闭
        socket.close();
    }
}

接收消息

public class UdpServerDemo02 {
    public static void main(String[] args) throws Exception {
        //1. 开放端口
        DatagramSocket socket = new DatagramSocket(10000);
        //2. 接收数据包
        byte[] buffer = new byte[1024];
        DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
        // 阻塞接收
        socket.receive(packet);
        System.out.println( new String(packet.getData(), 0, packet.getLength()));
        //3. 关闭连接
        socket.close();
    }
}

如咨询的场景

public class UdpSenderDemo01 {
    public static void main(String[] args) throws Exception {
        DatagramSocket socket = new DatagramSocket(10000);
        // 准备数据:控制台读取 System.in
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        while (true) {
            String data = reader.readLine();
            byte[] datas = data.getBytes();
            DatagramPacket packet = new DatagramPacket(
                    datas,
                    0,
                    datas.length,
                    new InetSocketAddress("localhost", 6666)
            );
            socket.send(packet);
            if ("bye".equals(data)) {
                break;
            }
        }

        socket.close();
    }
}
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);
            // 断开连接
            byte[] data = packet.getData();
            String receiveData = new String(data, 0, data.length);
            System.out.println(receiveData);
            if ("bye".equals(receiveData)) {
                break;
            }
        }
        socket.close();
    }
}

在线咨询:两个人都可以是发送方,也都可以是接收方

发送方

public class TalkSend implements Runnable {
    DatagramSocket socket = null;
    BufferedReader reader = null;
    private int fromIp;
    private String toIp;
    private int toPort;

    public TalkSend(int fromIp, String toIp, int toPort) throws Exception {
        this.fromIp = fromIp;
        this.toIp = toIp;
        this.toPort = toPort;

        this.socket = new DatagramSocket(fromIp);
        this.reader = new BufferedReader(new InputStreamReader(System.in));
    }

    @Override
    public void run() {
        try {
            // 准备数据:控制台读取 System.in
            while (true) {
                String data = reader.readLine();
                byte[] datas = data.getBytes();
                DatagramPacket packet = new DatagramPacket(
                        datas,
                        0,
                        datas.length,
                        new InetSocketAddress(this.toIp, this.toPort)
                );
                socket.send(packet);
                if ("bye".equals(data)) {
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        socket.close();
    }
}

接收方

public class TalkReceive implements Runnable {

    DatagramSocket socket = null;
    private int port;
    private String msgFrom;

    public TalkReceive(int port, String msgFrom) throws Exception {
        this.port = port;
        this.msgFrom = msgFrom;
        socket = new DatagramSocket(this.port);
    }

    @Override
    public void run() {
        while (true) {
            try {
                // 准备接收包裹
                byte[] container = new byte[1024];
                DatagramPacket packet = new DatagramPacket(container, 0, container.length);
                // 阻塞式接收
                socket.receive(packet);
                // 断开连接
                byte[] data = packet.getData();
                String receiveData = new String(data, 0, data.length);
                System.out.println(msgFrom + ":" + receiveData);
                if ("bye".equals(receiveData)) {
                    break;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        socket.close();
    }
}

测试:学生线程

public class TalkStudent {
    public static void main(String[] args) throws Exception {
        // 开启两个线程
        new Thread(new TalkSend(7777, "localhost", 10000)).start();
        new Thread(new TalkReceive(8888, "老师")).start();
    }
}

测试:老师线程

public class TalkTeacher {
    public static void main(String[] args) throws Exception {
        new Thread(new TalkSend(5555, "localhost", 8888)).start();
        new Thread(new TalkReceive(10000, "学生")).start();
    }
}

URL

http://www.baidu.com/

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

DNS域名解析

协议://ip地址:端口/项目名/资源
public class UrlDemo02 {
    public static void main(String[] args) throws Exception {
        //下载地址
        URL url = new URL("https://m701.music.126.net/20200724114352/48a179e4bbf0205c0a711aa07bd689b1/jdyyaac/5409/060b/5253/ccf875c05f1a97a210f7e926d421c52d.m4a");
        //连接下载资源
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        InputStream inputStream = conn.getInputStream();
        FileOutputStream fos = new FileOutputStream("有何不可.m4a");
        byte[] bytes = new byte[1024];
        int len;
        while ((len = inputStream.read(bytes)) != -1) {
            //读取数据
            fos.write(bytes, 0, len);
        }
        fos.close();
        inputStream.close();
        conn.disconnect();
    }
}
1
https://gitee.com/elonchung/Java-Review.git
git@gitee.com:elonchung/Java-Review.git
elonchung
Java-Review
Java-Review
master

搜索帮助