day13-网络编程

YangeIT大约 20 分钟JavaSe网络编程

day13-网络编程

跳转到页底(每日作业)[1]

今日目标

  • 网络编程
    • 网络编程三要素 🍐 ❤️
    • UDP通讯 🚀 🍐
    • TCP通讯 🍐 ✏️完成案例即可
    • TCP和UDP的区别 🍐 ❤️

前置知识

  1. 完成过字节流复制文件的案例
  2. 理解字节流复制文件的传输过程
  3. 理解文件是由字节组成的
  4. 曾经有过发送图片给朋友,却因为网络问题,失败的经历(如图👉)

一、网络编程概述 🚩

网络编程:编写的应用程序可以与网络上其他设备中的应用程序进行数据交互

网络编程的作用:

  1. 如我们经常用的微信收发消息就需要用到网络通信的技术
  2. 如我们打开浏览器可以浏览各种网络、视频等也需要用到网络编程的技术

Java提供的网络编程的解决方案:

  1. 在java.net包下提供了诸多类,实现网络编程

网络通信的基本架构:

  1. CS架构(Client 客户端/Server服务端)
  2. BS架构(Brower 浏览器/Server服务端)
  • CS架构的特点: CS架构需要用户在自己的电脑或者手机上安装客户端软件,然后由客户端软件通过网络连接服务器程序,由服务器把数据发给客户端,客户端就可以在页面上看到各种数据了。

1668262460269xxx

不管是CS、还是BS都是需要用到网络编程的相关技术

总结

课堂作业

  1. 说出你日常生活中,哪些软件是CS架构,哪些软件是BS架构的?🎤
  2. 简单说说CS架构和BS架构的各自的优点?🎤

二、网络编程三要素 🚩 🍐 ❤️

网络编程三要素:IP地址、端口号、通信协议

1668262831222
1668262831222

如下图所示:假设现在要从一台电脑中的微信上,发一句“你愁啥?”到其他电脑的微信上,流程如下

1.先通过ip地址找到对方的电脑
2.再通过端口号找到对方的电脑上的应用程序
3.按照双方约定好的规则发送、接收数据
1668263019076
1668263019076

总结

实操1:通过分析浏览器发送的请求,熟悉网络编程三要素 👇 👇

点击查看步骤
  1. 浏览器打开百度
  2. 按住F12或者在设置中,进入开发者工具模式 image
  3. 选择网络或者network tab栏目,然后刷新网站,观察
image
image

1️⃣ 2.1 IP地址

IP地址

IP(Ineternet Protocol)全称互联网协议地址,是分配给网络设备的唯一表示。

IP地址分为:IPV4地址、IPV6地址

IPV4地址由32个比特位(4个字节)组成,如果下图所示,但是由于采用二进制太不容易阅读了,于是就将每8位看成一组,把每一组用十进制表示(叫做点分十进制表示法)。所以就有了我们经常看到的IP地址形式,如:192.168.1.66

1668263179793
1668263179793

如果想查看本机的IP地址,可以在命令行窗口(win+R cmd),输入ipconfig命令查看,如下图所示

1668263481919
1668263481919

经过不断的发展,现在越来越多的设备需要联网,IPV4地址已经不够用了(255 * 255 * 255 * 255=约42亿)

域名

域名是一个IP地址上的面具 。一个域名的目的是便于记忆和沟通的一组服务器的地址

如:百度的域名:https://www.baidu.com/open in new window 对应的ip地址是:14.119.104.189

域名如何找到匹配IP?

域名和IP其实是一一对应的,由运营商来管理域名和IP的对应关系。我们在浏览器上敲一个域名时,首先由运营商的域名解析服务,把域名转换为ip地址,再通过IP地址去访问对应的服务器设备。

1668264280209
1668264280209

本地回送地址127.0.0.1,方便测试使用(因为电脑没插网线或者没连接Wifi的时候没有分配ip地址)

常见的几个关于控制台命令

ipconfig: 查看本机的ip地址
ping 域名/ip  检测当前电脑与指定的ip是否连通

ping命令出现以下的提示,说明网络是通过的

1668264499362
1668264499362

作业

🚩

  1. 使用win+R 输入cmd 打开控制台,输入ipconfig 查看本机的ip地址
image
image
  1. 或者打开网络适配器,查看网络详情,查看本机地址。或者打开飞秋查看你同学的网络地址
image
image
  1. 在Java类中使用InetAddress的api 获得本机地址(方法:getHostAddress)

2️⃣ 2.2 端口号

端口号

指的是计算机设备上运行的应用程序的标识,被规定为一个16位的二进制数据,范围(0~65535

端口号分类:了解

  • 周知端口:0~1023,被预先定义的知名应用程序占用(如:HTTP占用80,FTP占用21)
  • 注册端口:1024~49151,分配给用户经常或者某些应用程序
  • 动态端口:49152~65536,之所以称为动态端口,是因为它一般不固定分配给某进程,而是动态分配的。

常见的端口: 开发常见 👈

  1. 80端口 是http协议的端口
  2. 443端口 是https协议的端口
  3. 3306端口 是mysql数据库的端口
  4. 22端口 是文件上传的端口

注意:同一个计算机设备中,不能出现两个应用程序,用同一个端口号 1668267533206

总结

课堂作业

  1. 端口号有什么作用?🎤

3️⃣ 2.4 协议

协议

网络上通信的设备,事先规定的连接规则,以及传输数据的规则被称为网络通信协议。

作用:

1668267760295
1668267760295

协议的种类:了解传输层协议

只要按照OSI网络参考模型制造的设备,就可以在国际互联网上互联互通

1668267891624
1668267891624
  • UDP协议特点
1668268046104
1668268046104

总结

课堂作业

  1. UDP和tcp协议,哪个更靠谱?🎤
  2. UDP协议应用场景是什么?

三、UDP通信代码(案例) 🚩

1️⃣ 3.1 入门程序 ✏️

UDP入门程序

学习基于UDP协议通信的程序

UDP入门案例前置知识:

  1. 了解 UDP是面向无连接的、不需要确认双方是否存在,是不可靠的协议
  2. Java提供了一个类叫DatagramSocket来完成基于UDP协议的收发数据
  3. 使用DatagramSocket收发数据时,数据要以数据包的形式体现,一个数据包限制在64KB以内大小有限制
  4. 有发送端和接收端2个程序

代码操作

需求:客户端程序发一个字符串数据给服务端,服务端程序接收数据并打印。

public class Client {
    public static void main(String[] args) throws Exception {
//        创建数据报套接字并将其绑定到本机地址上的任何可用端口
        // 1、创建客户端对象(发韭菜出去的人)
        DatagramSocket socket = new DatagramSocket();

        // 2、创建数据包对象封装要发出去的数据(创建一个韭菜盘子)
       /* public DatagramPacket(byte buf[], int length,
             InetAddress address, int port)
               参数一:封装要发出去的数据。
               参数二:发送出去的数据大小(字节个数)
               参数三:服务端的IP地址(找到服务端主机)
               参数四:服务端程序的端口。
             */
        byte[] bytes = "发送端:我是老王,你在吗".getBytes();
        DatagramPacket packet = new DatagramPacket(bytes, bytes.length
                , InetAddress.getLocalHost(),  22222);

        // 3、开始正式发送这个数据包的数据出去了
        socket.send(packet);

        System.out.println("客户端数据发送完毕~~~");
        socket.close(); // 释放资源!
    }
}


总结

课堂作业

  1. 参考上述的代码,练习一下UDP的入门程序,体会下,发了消息后,就不管不顾了的特点!🎤

2️⃣ 3.2 进阶程序 ✏️ 增加一个while循环

UDP进阶程序

需求:实现客户端不断的发数据,而服务端能不断的接收数据,客户端发送exit时客户端程序退出。

代码操作

/**
 * 目标:完成UDP通信快速入门:实现客户端反复的发。
 */public class Client {
    public static void main(String[] args) throws Exception {
//        创建数据报套接字并将其绑定到本机地址上的任何可用端口
        // 1、创建客户端对象(发韭菜出去的人)
        DatagramSocket socket = new DatagramSocket();

        // 2、创建数据包对象封装要发出去的数据(创建一个韭菜盘子)
       /* public DatagramPacket(byte buf[], int length,
             InetAddress address, int port)
               参数一:封装要发出去的数据。
               参数二:发送出去的数据大小(字节个数)
               参数三:服务端的IP地址(找到服务端主机)
               参数四:服务端程序的端口。
             */

         Scanner scanner = new Scanner(System.in);

        while (true) {
             String msg = scanner.next();
            // 一旦发现用户输入的exit命令,就退出客户端
            if("exit".equals(msg)){
                System.out.println("欢迎下次光临!退出成功!");
                socket.close(); // 释放资源
                break; // 跳出死循环
            }

            DatagramPacket packet = new DatagramPacket(msg.getBytes(), msg.getBytes().length
                    , InetAddress.getLocalHost(),  22222);
            // 3、开始正式发送这个数据包的数据出去了
            socket.send(packet);
        }


    }
}

作业

🚩 1. 参考下列提示,完成UDP入门案例(1发1接)

  • 发送端
/**
 * 目标:完成UDP通信快速入门:实现1发1收。
 *
 *
 * 1. 创建客户端对象(发韭菜出去的人) DatagramSocket
 * 2. 创建数据包对象封装要发出去的数据(创建一个韭菜盘子) DatagramPacket
 * 3. 开始正式发送这个数据包的数据出去了 send
 * 4. 释放资源! close
 *
 */
public class Client {
    public static void main(String[] args) throws Exception {

// 书写代码


    }
}












 
 
 
 


  • 接收端
/**
 * 目标:完成UDP通信快速入门-服务端开发
 * 1.  创建一个服务端对象(创建一个接韭菜的人) 注册端口   DatagramSocket
 * 2. 创建一个数据包对象,用于接收数据的(创建一个韭菜盘子) DatagramPacket(数组,数组长度)
 * 3. 开始正式使用数据包来接收客户端发来的数据 receive(包裹)
 * 4. 从包裹中获得数据,并且解析成String(byte数组,0,包裹的长度)
 * 5. 释放资源
 */
public class Server {
    public static void main(String[] args) throws Exception {

// 书写代码


    }
}










 
 
 
 


四、TCP通信代码(案例) 🚩 ✏️

1️⃣ 4.1 TCP入门程序 说一句话

TCP入门程序

前置知识:

  1. socket协议是面向连接、通讯可靠的协议
  2. socket协议需要三次握手建立连接,断开需要4次

Socket完成TCP通信的流程:

  1. 当创建Socket对象时,就会在客户端和服务端创建一个数据通信的管道,在客户端和服务端两边都会有一个Socket对象访问这个通信管道
  2. 现在假设客户端要发送一个在一起给服务端,客户端这边先需要通过Socket对象获取到一个字节输出流,通过字节输出流写数据到服务端
  3. 服务端这边通过Socket对象可以获取字节输入流,通过字节输入流就可以读取客户端写过来的数据,并对数据进行处理。
  4. 服务端处理完数据之后,假设需要把没感觉发给客户端端,那么服务端这边再通过Socket获取到一个字节输出流将数据写给客户端
  5. 客户端这边再获取输入流,通过字节输入流来读取服务端写过来的数据。
1668270124031
1668270124031

注意:写代码之前一定要理解上图,不然输入和输出流,容易晕!

代码操作

/**
 *  目标:完成TCP通信快速入门-客户端开发:实现1发1收。
 */public class Client {
    public static void main(String[] args) throws Exception {
        // 1、创建Socket对象,并同时请求与服务端程序的连接。(ip和端口是服务端的)
        Socket socket = new Socket("127.0.0.1", 22222);

        // 2、从socket通信管道中得到一个字节输出流,用来发数据给服务端程序。
        OutputStream os = socket.getOutputStream();

        // 4、开始写数据出去了
        os.write("在一起,好吗?".getBytes());
        os.close();

        socket.close(); // 释放连接资源
    }
}

作业

🚩 1. 参考下列提示,完成TCP入门案例

  1. 对比TCP和UDP代码,能体会他们的区别吗?哪个是不管不顾,哪个是确保一定要收到!

2️⃣ 4.2 TCP入门程序 说多句话

TCP进阶程序

实现客户端可以反复的发消息出去,实现服务端反复接收消息

  1. 反复发,反复接收消息,说明要用到循环----> 死循环
  2. 死循环说明程序无法停止,输入exit出发break 跳出循环,结束程序
image
image

代码操作

/**
 *  目标:完成TCP通信快速入门-客户端开发:实现客户端可以反复的发消息出去
 */public class Client {
    public static void main(String[] args) throws Exception {
        // 1、创建Socket对象,并同时请求与服务端程序的连接。(ip和端口是服务端的)
        Socket socket = new Socket("127.0.0.1", 22222);

        // 2、从socket通信管道中得到一个字节输出流,用来发数据给服务端程序。
        OutputStream os = socket.getOutputStream();

        Scanner sc = new Scanner(System.in);

        while (true) {
            System.out.println("请说:");
            String msg = sc.nextLine();

            // 一旦用户输入了exit,就退出客户端程序
            if("exit".equals(msg)){
                System.out.println("欢迎您下次光临!退出成功!");
                os.close();
                socket.close();
                break;
            }

            // 4、开始写数据出去了
            os.write(msg.getBytes());
            os.flush();
        }
    }
}

运行效果:image

作业

🚩 1. 尝试完成上述可以发多句话的TCP

3️⃣ 4.3 TCPPlus程序之线程池优化 🍐 ✏️

TCPPlus程序之线程池优化

为了让服务端能够支持多个客户端通信,就需要用到多线程技术。具体的实现思路如下图所示:每当有一个客户端连接服务端,在服务端这边就为Socket开启一条线程取执行读取数据的操作,来多少个客户端,就有多少条线程。按照这样的设计,服务端就可以支持多个客户端连接了。

1668315156739
1668315156739

代码操作

/**
 *  目标:完成TCP通信快速入门-客户端开发:实现客户端可以反复的发消息出去
 *  1. 和上述案例一样
 */
public class Client {
    public static void main(String[] args) throws Exception {
        // 1、创建Socket对象,并同时请求与服务端程序的连接。(ip和端口是服务端的)
        Socket socket = new Socket("127.0.0.1", 22222);

        // 2、从socket通信管道中得到一个字节输出流,用来发数据给服务端程序。
        OutputStream os = socket.getOutputStream();

        Scanner sc = new Scanner(System.in);

        while (true) {
            System.out.println("请说:");
            String msg = sc.nextLine();

            // 一旦用户输入了exit,就退出客户端程序
            if("exit".equals(msg)){
                System.out.println("欢迎您下次光临!退出成功!");
                os.close();
                socket.close();
                break;
            }

            // 4、开始写数据出去了
            os.write(msg.getBytes());
            os.flush();
        }
    }
}

运行效果:image

作业

🚩 1. 配合上述的运行效果图,尝试完成上述线程池的TCP入门程序

  1. 客户端不变,
  2. 服务端中创建线程池
  3. 将服务端中的处理消息的部分 抽取为Runnable

晚间作业

今天的作业是将今天的案例重复敲一遍以及额外还有作业,理解网络编程的作用,以及TCP和UDP的区别,还有常用的网络命令行指令。

  • 建议也是要求:
    1. 做题之前先审题,标注可能用到的技术
    2. 做题要写注释,然后写代码
    3. 先问自己,再看笔记,实在不知道再问他人

  1. 页底标记 ↩︎