JAVASE23天从入门到精通_Day21

本文介绍了网络编程的基本概念,包括IP地址(IPv4和IPv6)、端口号的范围及作用,以及UDP和TCP协议的区别。详细讲解了UDP的发送和接收数据流程,以及TCP的面向连接特性。此外,还阐述了类加载的过程,从加载、链接(验证、准备、解析)到初始化的各个阶段。最后,提到了类加载器的分类和类加载机制,如双亲委派模型。
摘要由CSDN通过智能技术生成
网络编程
网络编程: 实现了PC和PC之间的数据交互;

192.168.16.120
网络编程的三要素
寄快递 :
	收件人地址 : 帮快递员找到收件人所居住位置;
	收件人的电话和姓名 : 精准的在地址位置找到收件人;
	快递公司 : 邮政,顺丰,京东,其他
	
网络通讯 : 	
	IP地址 : 帮助程序找到接收数据的 -> 收件人地址
	端口号 : 计算机中可以通讯的软件的id -> 收件人的电话和姓名
	网络协议 : UDP/TCP -> 快递公司
IP地址
IP地址 : 计算机在网络中的位置

IP地址的表现形式:
	IPV4: 192.168.16.120
        十进制点分法表示的IP地址
        一个点位占用1个字节,一个点位最大的值 255
        16 : 网段
        119 : 地址
        1 : 网关地址 192.168.16.2 -> ping 网关来检测网络情况
        255 : 广播地址 192.168.17.255 -> 群发消息
	IPV6:   fe80::116a:5543:1ff7:b519
		十六进制冒分法表示的IP地址
		
DNS服务器:
	www.baidu.com -> DNS服务器 -> 百度公司服务的IP地址
端口号
端口号 : 计算机中可以通讯的软件的id -> 收件人的电话和姓名

端口号范围 : 0-65535 
    
端口号在范围内可以随意设置,但是一定不能重复
	1. 0-1000号不要用,早就被占用了
	2. 8080,80,3306,8848..
InetAddress
InetAddress : 表示IP地址的类
	通过InetAddress可以获取指定主机的IP地址对象
	
获取IP地址对象:
	static InetAddress getByName(String host)  : 传入主机名/主机的IP地址,获取该主机的IP地址对象
    static InetAddress[] getAllByName(String host)   : 传入主机名/主机的IP地址,获取该主机的IP地址对象
    static InetAddress getLocalHost()  :快速获取当前主机的IP地址对象
    
成员方法:
	 String getHostName()  : 通过主机对象获取该主机对象的主机名
	 String getHostAddress()  : 通过主机对象获取该主机的IP地址(String)
UDP网络协议
UDP网络协议 : 面向无连接的网络协议

在这里插入图片描述

UDP发送端
UDP发送端 : DatagramSocket

构造方法:
	DatagramSocket() 
       
发送数据:
	void send(DatagramPacket p)  
UDP接收端
UDP接收端 : DatagramSocket

构造方法:
	DatagramSocket(int port) 
        
接收数据:
	void receive(DatagramPacket p) 
        
拆数据的方法在DatagramPacket类中:
	 InetAddress getAddress()  : 获取发件人的ip地址对象
	 byte[] getData() : 拿数据报包中的数据数组  --> 不用的  
	 int getLength()  : 获取真实数据的长度
DatagramPacket
DatagramPacket : 数据报包的类

发送端的DatagramPacket对象的创建:
	DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port) 
        byte[] buf, int offset, int length : 要发送的数据 //商品
        InetAddress address: IP地址对象 //收件人地址 Ip地址
        int port : 端口号 //收件人姓名和电话  端口号

接收端的DatagramPacket对象的创建:    
	DatagramPacket(byte[] buf, int length) 
        byte[] buf : 用来装数据的字节数组
        int length : 接收的长度
TCP协议
TCP协议 :  面向连接的网络协议

TCP协议核心思路:
	三次握手: 连接
	四次挥手: 断开连接

在这里插入图片描述

TCP客户端代码编写
TCP客户端 : Socket

构造方法:
	Socket(InetAddress address, int port) 
	Socket(String host, int port)   --> 传入字符串类型的主机名/主机IP 和 主机中软件的端口号  
	
发送数据的方法 : 通过IO流进行数据的传输
	OutputStream getOutputStream()  : 通过Socket对象获取通讯的输出流对象
	//通过输出流对象往外写数据 -> write
TCP服务端代码编写
TCP服务器 : ServerSocket

构造方法:
	ServerSocket(int port) 指明服务器端口号即可(客户端发数据给服务器要求客户端指定的端口号和服务器一致)
        
接收数据的方法:通过IO流进行数据的传输
	//在TCP协议中通讯,所有的输出/输入流对象都是通过Socket对象去获取的
	 Socket accept() 侦听并接受到客户端套接字的连接。 
	 Socket类: InputStream getInputStream()
     Socket类:
类加载的过程
	当程序主动使用某个类时,如果该类还未被加载到内存中,则JVM会通过加载、连接、初始化3个步骤来对该类进行初始化。如果没有意外,JVM将会连续完成3个步骤,所以有时也把这个3个步骤统称为类加载或类初始化。
	
类加载器 : ClassLoader	

在这里插入图片描述

加载

​ 加载指的是将类的class文件读入到内存,并为之创建一个java.lang.Class对象(字节码对象),也就是说,当程序中使用任何类时,系统都会为之建立一个java.lang.Class对象(一个类只可能有一个字节码对象)。

现在 : 对象.getClass() == 类名.class --> 前面的对象是否属于后面的类型
	stu.getClass() -> 通过学生对象获取的学生类字节码对象
	Student.class -> 通过学生类的类属性拿到的学生类字节码对象
		//一个类只可能有一个字节码对象
	stu.getClass()	== Student.class; true 说明前面的对象是属于后面这个类型的!
    
以前的写法: 对象 instanceof 类    判断前面的对象是否属于后面的类型的

类的加载由类加载器(ClassLoader)完成,类加载器通常由JVM提供,这些类加载器也是前面所有程序运行的基础,JVM提供的这些类加载器通常被称为系统类加载器。除此之外,开发者可以通过继承ClassLoader基类(类加载器的基类)来创建自己的类加载器。

通过使用不同的类加载器,可以从不同来源加载类的二进制数据(字节码文件),通常有如下几种来源。

  1. 从本地文件系统加载class文件,这是前面绝大部分示例程序的类加载方式。

  2. 从JAR包加载class文件,这种方式也是很常见的,JDBC编程时用到的数据库驱动类就放在JAR文件中,JVM可以从JAR文件中直接加载该class文件。

  3. 通过网络加载class文件。
    把一个Java源文件动态编译,并执行加载。

    类加载器通常无须等到“首次使用”该类时才加载该类,Java虚拟机规范允许系统预先加载某些类。

链接

​ 当类被加载之后,系统为之生成一个对应的Class对象,接着将会进入连接阶段,连接阶段负责把类的二进制数据(字节码对象)合并到JRE中。类连接又可分为如下3个阶段。

1)验证:验证阶段用于检验被加载的类是否有正确的内部结构,并和其他类协调一致。Java是相对C++语言是安全的语言,例如Java有C++不具有的数组越界的检查。这本身就是对自身安全的一种保护。验证阶段是Java非常重要的一个阶段,它会直接的保证应用是否会被恶意入侵的一道重要的防线,越是严谨的验证机制越安全。验证的目的在于确保Class文件的字节流中包含信息符合当前虚拟机要求,不会危害虚拟机自身安全。其主要包括四种验证,文件格式验证,元数据验证,字节码验证,符号引用验证。

四种验证做进一步说明:

文件格式验证:主要验证字节码文件是否符合Class文件格式规范,并且能被当前的虚拟机加载处理。例如:主,次版本号是否在当前虚拟机处理的范围之内。常量池中是否有不被支持的常量类型。指向常量中的索引值是否存在不存在的常量或不符合类型的常量。

元数据验证:对字节码描述的信息进行语义的分析,分析是否符合java的语言语法的规范。

字节码验证:最重要的验证环节,分析数据流和控制,确定语义是合法的,符合逻辑的。主要的针对元数据验证后对方法体的验证。保证类方法在运行时不会有危害出现。

符号引用验证:主要是针对符号引用转换为直接引用的时候,是会延伸到第三解析阶段,主要去确定访问类型等涉及到引用的情况,主要是要保证引用一定会被访问到,不会出现类等无法访问的问题。

2)准备:类准备阶段负责为类的静态变量分配内存,并设置默认初始值(系统默认值)。

3)解析:将类的二进制数据中的符号引用替换成直接引用。说明一下:符号引用:符号引用是以一组符号来描述所引用的目标,符号可以是任何的字面形式的字面量,只要不会出现冲突能够定位到就行。布局和内存无关。直接引用:是指向目标的指针,偏移量或者能够直接定位的句柄。该引用是和内存中的布局有关的,并且一定加载进来的。

初始化

​ 初始化是为类的静态变量赋予正确的初始值(程序员给静态成员变量赋的值),准备阶段和初始化阶段看似有点矛盾,其实是不矛盾的,

如果类中有语句:private static int a = 10,它的执行过程是这样的,首先字节码文件被加载到内存后,先进行链接的验证这一步骤,验证通过后准备阶段,给a分配内存,因为变量a是static的,所以此时a等于int类型的默认初始值0,即a=0,然后到解析,到初始化这一步骤时,才把a的真正的值10赋给a,此时a=10。

总结:
	加载: 生成类的字节码对象
    链接:
		验证: 校验字节码对象中的成员是否符合Java类规范
        准备: 加载类中静态成员并赋予系统默认值
        解析: 把类中的符号引用替换成直接引用
    初始化: 把类中静态成员的默认值替换成真实值;

在这里插入图片描述

类何时加载
  1. 创建类的实例,也就是new一个对象
  2. 访问某个类或接口的静态变量,或者对该静态变量赋值
  3. 调用类的静态方法
  4. 反射(Class.forName(“全类名”))
  5. 初始化一个类的子类(会首先初始化子类的父类)
  6. JVM启动时标明的启动类,即文件名和类名相同的那个类

类何时被加载: 类第一次被使用的时候加载

类加载器
类加载器负责加载所有的类,其为所有被载入内存中的类生成一个java.lang.Class实例对象。一旦一个类被加载到JVM中,同一个类就不会被再次载入了。
  1. 根类加载器(bootstrap classloader):它用来加载 Java 的核心类,是用原生代码来实现的,并不继承自 java.lang.ClassLoader(负责加载$JAVA_HOME中jre/lib/rt.jar里所有的class,由C++实现,不是ClassLoader子类)。由于引导类加载器涉及到虚拟机本地实现细节,开发者无法直接获取到启动类加载器的引用,所以不允许直接通过引用进行操作。
  2. 扩展类加载器(extensions classloader):它负责加载JRE的扩展目录,lib/ext或者由java.ext.dirs系统属性指定的目录中的JAR包的类。由Java语言实现,父类加载器为null。
  3. 系统类加载器(system class loader):被称为系统(也称为应用)类加载器,它负责在JVM启动时加载来自Java命令的-classpath选项、java.class.path系统属性,或者CLASSPATH换将变量所指定的JAR包和类路径。程序可以通过ClassLoader的静态方法getSystemClassLoader()来获取系统类加载器。如果没有特别指定,则用户自定义的类加载器都以此类加载器作为父加载器。
  4. 自定义加载器(custom class loader): 我要指定一些类由某个类加载器加载 那么就可以自定义类加载器
类加载器加载Class的8个步骤
1. 检测此Class是否载入过,即在缓冲区中是否有此Class,如果有直接进入第8步,否则进入第2步。
2. 如果没有父类加载器,则要么Parent是根类加载器,要么本身就是根类加载器,则跳到第4步,如果父类加载器存在,则进入第3步。
3. 请求使用父类加载器去载入目标类,如果载入成功则跳至第8步,否则接着执行第5步。
4. 请求使用根类加载器去载入目标类,如果载入成功则跳至第8步,否则跳至第7步。
5. 当前类加载器尝试寻找Class文件,如果找到则执行第6步,如果找不到则执行第7步。
6. 从文件中载入Class,成功后跳至第8步。
7. 抛出ClassNotFountException异常。
8. 返回对应的java.lang.Class对象。
类加载机制-双亲委派模型

在这里插入图片描述

类加载器使用场景(重要)
类加载器的功能: 快速获取当前类所在模块src文件夹根目录下的文件
    
ClassLoader: 类加载器的类(类加载器的基类)   
    static ClassLoader getSystemClassLoader() : 获取到系统类加载器对象
    InputStream getResourceAsStream(String fileName): 快速的获取传入文件路径指向的文件
    	String fileName: 文件路径 --> 相对路径写: 相对路径的起点是src文件夹
            
static InputStream getSystemResourceAsStream(String name):直接获取输入流对象 -> 推荐方法       
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值