【DAY23】
文章目录
- 【DAY23】
- 一.网络编程
- 1)三要素
- 1.1)IP
- InetAddress类的使用
- 1.2)端口号
- 1.3)协议
- 2.1)UDP协议发送数据
- 2.2)UDP协议接收数据
- 2.3)UDP的三种通信方式
- 3.1)TCP协议的发送和接收
- 3.2)中文乱码问题
- 3.3)三次握手四次挥手
- 二.反射
- 1)概述
- 2)获取class对象的三种方式
- 3)反射获取构造方法
- 4)反射获取成员变量
- 5)反射获取成员方法
- 三.动态代理
一.网络编程
在通信协议下不同计算机上运行的程序,进行的数据传输
应用场景:计算机跟计算机之间通过网络
Java中使用java.net包下的技术轻松开发出常见的网络应用程序
常见的软件架构:
- CS:Client/Server 在用户本地需要下载并安装客户端程序,在远程有一个服务端程序 eg:QQ
- 优点:画面精美,用户体验好
- 缺点:需要开发客户端也需要开发服务端。用户需要下载和更新
- BS:Browser/Server 只需要一个浏览器,用户通过不同网址,客户访问不同的服务器 eg:淘宝
- 优点:不需要开发客户端,只需要页面+服务端,用户不需要下载打卡浏览器就能使用
- 缺点:如果应用过大,用户体验受到影响
1)三要素
IP:设备在网络中的地址,是唯一的表示
端口号:应用程序在设备中的唯一表示
协议:数据在网络中传输的规则,常见的协议有UDP,TCP,http,ftp
1.1)IP
互联网协议地址,上网设备在网络中的地址是分配给上网设备的数字标签
分类:
-
IPv4互联网通信协议第四版
采用32位地址长度,分为4组,最多只有2^32个IP,2019年11.26全部分配完毕
可以用局域网解决IP不够的问题
-
IPv6互联网通信协议第六版
采用128位地址长度,分为8组 ,最多有2^128个IP
IPv4的细节
1.分类:公网地址(万维网使用)和私有地址(区域网使用)
192.168开头的就是私有地址,范围为192.168.0.0—192.168.255.255,专门为组织机构内部使用
2.特殊IP地址:127.0.0.1,也可以是localhost:是回送地址也称本地回送地址,也称本机IP,永远只会寻找当前所在本机
常用的CMD
- ipconfig:查看本机IP地址
- ping:检查网络是否连通
InetAddress类的使用
表示IP地址
方法 | 说明 |
---|---|
static InetAddress getByName(String host) | 确定主机名称的IP地址,主机名称可以是机器名称也可以是IP地址 |
String getHostName() | 获取此IP地址的主机名 |
String getHostAddress() | 返回文本显示的IP地址字符串 |
public class t1 {public static void main(String[] args) throws UnknownHostException {//1.获取InetAddress的对象InetAddress address = InetAddress.getByName("LAPTOP-K3EOH2DK");//"设备名"System.out.println(address);//LAPTOP-K3EOH2DK/192.168.1.32String name = address.getHostName();System.out.println(name);//LAPTOP-K3EOH2DKString ip = address.getHostAddress();System.out.println(ip);//192.168.1.32}
}
1.2)端口号
应用程序在设备中唯一的标识
有两个字节表示的整数,取值范围:065535,其中01023之间的端口号用于一些知名的网络访问或者应用
一个端口号只能被一个应用程序使用
1.3)协议
计算机网络中连接和通信的规则被称为网络通信协议
- OSI参考模型:世界互联协议标准,全球通信规范,单模型过于理想化,未能在因特网上进行广泛推广
- TCP/IP参考模型(或TCP/IP协议):事实上的国际标准
UDP协议:
- 用户数据报协议
- UDP是面向无连接通信协议,速度快,有大小限制一次最多发送64K,数据不安全,易丢失数据
TCP协议:
- 传输控制协议
- TCP是面向连接通信协议,速度慢,没有大小限制,数据安全
2.1)UDP协议发送数据
public class t1 {public static void main(String[] args) throws IOException {//1.创建对象//绑定端口号,通过这个端口往外发送//空参:所有可能的端口中随机一个进行使用//有参:指定端口号进行绑定DatagramSocket ds = new DatagramSocket();//2.打包数据String str = "你好你好你好你好你好";byte[] bytes = str.getBytes();InetAddress address = InetAddress.getByName("192.168.1.32");int port = 10086;//端口号DatagramPacket dp = new DatagramPacket(bytes, bytes.length, address, port);//3.发送数据ds.send(dp);//4.释放数据ds.close();}
}
2.2)UDP协议接收数据
public class T2 {public static void main(String[] args) throws IOException {//1.创建DatagramSocketDatagramSocket ds = new DatagramSocket(10086);//2.接收数据包byte[] bytes = new byte[1024];DatagramPacket dp = new DatagramPacket(bytes, bytes.length);ds.receive(dp);//3.解析数据包byte[] data = dp.getData();int len = dp.getLength();InetAddress address = dp.getAddress();int port = dp.getPort();System.out.println("接收到数据" + new String(data,0,len));System.out.println("该数据是从" + address + "这台电脑中的" + port + "这个接口发出的");//4.释放数据ds.close();}
}
先运行接收端再运行发送端
2.3)UDP的三种通信方式
-
单播
一对一
-
组播
一对组
组播地址:224.0.0.0~239.255.255.255 其中224.0.0.0~224.0.0.255为预留的组播地址
-
广播
一对局域网中的所有设备
广播地址:255.255.255.255
组播
public class t1 {public static void main(String[] args) throws IOException {//组播//1.创建对象MulticastSocket ms = new MulticastSocket();//2.打包数据String str = "你好你好你好你好你好";byte[] bytes = str.getBytes();InetAddress address = InetAddress.getByName("224.0.0.1");int port = 10000;//端口号DatagramPacket dp = new DatagramPacket(bytes, bytes.length, address, port);//3.发送数据ms.send(dp);//4.释放数据ms.close();}
}
public class T2 {public static void main(String[] args) throws IOException {//1.创建对象MulticastSocket ms = new MulticastSocket(10000);//2.将当前本机添加到224.0.0.1的这一组中InetAddress adress = InetAddress.getByName("224.0.0.1");ms.joinGroup(adress);//3.接收数据包byte[] bytes = new byte[1024];DatagramPacket dp = new DatagramPacket(bytes, bytes.length);ms.receive(dp);//4.解析数据包byte[] data = dp.getData();int len = dp.getLength();InetAddress address = dp.getAddress();int port = dp.getPort();System.out.println("接收到数据" + new String(data,0,len));System.out.println("该数据是从" + address + "这台电脑中的" + port + "这个接口发出的");//5.释放数据ms.close();}
}
广播
public class t1 {public static void main(String[] args) throws IOException {//组播//1.创建对象MulticastSocket ms = new MulticastSocket();//2.打包数据String str = "你好你好你好你好你好";byte[] bytes = str.getBytes();InetAddress address = InetAddress.getByName("255.255.255.255");int port = 10000;//端口号DatagramPacket dp = new DatagramPacket(bytes, bytes.length, address, port);//3.发送数据ms.send(dp);//4.释放数据ms.close();}
}
3.1)TCP协议的发送和接收
客户端
-
创建客户端的对象Socket对象(Socket)与自动服务器端连接
Socket(String host,int port)
-
获取输出流,写数据
OutputStream getOutputStream()
-
释放数据
void close()
服务器
-
创建服务器端的Socket对象(ServerSocket)
ServerSocket(int port)
-
监听客户端连接,返回一个Socket对象
Socket accept()
-
获取输入流,读数据,并把数据显示在控制台
InputStream getInputStream()
-
释放资源
void close()
客户端
public class t1 {public static void main(String[] args) throws IOException {//1.创建对象Socket socket = new Socket("192.168.1.32",10086);//2.从连接通道中获取输出流OutputStream os = socket.getOutputStream();//写出数据os.write("你好你好你好你好你好".getBytes());//3.释放数据os.close();socket.close();}
}
服务端
public class T2 {public static void main(String[] args) throws IOException {//1.创建对象ServerSocket ss = new ServerSocket(10086);//2.监听客户端的连接Socket socket = ss.accept();//3.从连接通道中获取输入流读取数据InputStream is = socket.getInputStream();int b;while((b = is.read()) != -1) {System.out.println((char)b);}//4.释放资源socket.close();ss.close();}
}
3.2)中文乱码问题
乱码原因:一个中文三个字节,InputStream字节流一个一个字节读所有造成乱码
解决方法:用转换流把字节流转换为字符流
public class T2 {public static void main(String[] args) throws IOException {//1.创建对象ServerSocket ss = new ServerSocket(10086);//2.监听客户端的连接Socket socket = ss.accept();//3.从连接通道中获取输入流读取数据InputStream is = socket.getInputStream();InputStreamReader isr = new InputStreamReader(is);int b;while((b = isr.read()) != -1) {System.out.print((char)b);}//4.释放资源isr.close()socket.close();ss.close();}
}
3.3)三次握手四次挥手
二.反射
1)概述
反射允许对封装类的字段,方法和构造函数的信息进行编程访问
2)获取class对象的三种方式
-
Class.forName(“全类名”);
最常用
-
类名.class
一般更多是当做参数进行传递
-
类名.getClass();
当已经有了这个类的对象时才能使用
public class t1 {public static void main(String[] args) throws IOException, ClassNotFoundException {//1.法一//全类名:包名 + 类名Class clazz1 = Class.forName("T1.Student");//2.法二Class clazz2 = Student.class;//3.法三Student s = new Student();Class clazz3 = s.getClass();}
}
3)反射获取构造方法
public class t1 {public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException {//1.获取class字节码文件对象Class clazz = Class.forName("T1.Student");//2.获取构造方法Constructor[] cons = clazz.getConstructors();for (Constructor con : cons) {System.out.println(con);}Constructor[] cons2 = clazz.getDeclaredConstructors();for (Constructor con2 : cons2) {System.out.println(con2);}//获取单个Constructor con1 = clazz.getDeclaredConstructor();System.out.println(con1);Constructor con2 = clazz.getDeclaredConstructor(String.class);System.out.println(con2);}
}
4)反射获取成员变量
public class t1 {public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, NoSuchFieldException {//1.获取class字节码文件对象Class clazz = Class.forName("T1.Student");//2.获取成员变量Field[] fields = clazz.getFields();for (Field field : fields) {System.out.println(field);}Field[] fields2 = clazz.getDeclaredFields();for (Field field2 : fields2) {System.out.println(field2);}//获取单个Field name = clazz.getDeclaredField("name");//获取权限修饰符int modifiers = name.getModifiers();System.out.println(modifiers);}
}
5)反射获取成员方法
三.动态代理
特点:无侵入式的给代码增加额外的功能
为什么需要代理对象如果要干的事情太多可以通过代理转移部分职责
代理长什么样对象有什么方法想被代理,代理就一定要有相应的方法