Java_8_网络编程_反射_注解

网络编程

软件结构

C/S架构:全称为Client/Server结构,是指客户端和服务器结构。常见程序有QQ、迅雷等软件。用户体验效果好,对信息的安全控制较强,应用服务器运行数据负荷较轻,部分计算在客户端完成。

B/S结构:全称为Browser/Server结构,是指浏览器和服务器结构。常见浏览器有谷歌、火狐等。维护方便,占用空间少。

网络通信协议

TCP:

  • 传输控制协议 (Transmission Control Protocol)。TCP协议是面向连接的通信协议,即传输数据之前,在发送端和接收端建立逻辑连接,然后再传输数据,它提供了两台计算机之间可靠无差错的数据传输。

UDP:

  • 用户数据报协议(User Datagram Protocol)。UDP协议是一个面向无连接的协议。传输数据时,不需要建立连接,不管对方端服务是否启动,直接将数据、数据源和目的地都封装在数据包中,直接发送。每个数据包的大小限制在64k以内。它是不可靠协议,因为无连接,所以传输速度快,但是容易丢失数据。

三次握手:

  • TCP协议中,在发送数据的准备阶段,客户端与服务器之间的三次交互,以保证连接的可靠。
  • 第一次握手,客户端向服务器端发出连接请求,等待服务器确认。
  • 第二次握手,服务器端向客户端回送一个响应,通知客户端收到了连接请求。
  • 第三次握手,客户端再次向服务器端发送确认信息,确认连接。

OSI模型:

  • 应用层
  • 表示层
  • 会话层
  • 传输层
  • 网络层
  • 数据链路层
  • 物理层

TCP/IP模型:

  • 应用层(应用层、表示层、会话层)
  • 传输层TCP、UDP
  • 网络层IP、ARP、ICMP
  • 物理+数据链路层
IP地址-域名-端口号

ip地址:

  1. 概念:用于唯一标识网络中每台计算机
  2. 查看IP地址指令:ipconfig
  3. IP地址表示为十进制(xx.xx.xx.xx),范围0~255
  4. 组成:网络地址+主机地址
  5. IP4使用4字节32位,IP6使用16字节128位
  6. 本机域名:localhost/127.0.0.1

域名:

  1. 例如:www.baidu.com
  2. 为了解决记忆IP地址的困难,将IP地址映射为域名,访问时DNS会将域名解析成一个ip地址

端口号:

  1. 概念:用于标记计算机上某个特定的网络程序
  2. 表示形式:整数形式,范围0~65525
  3. 0~1024已被占用,如http-80、ftp-21、ssh-22
  4. 常见程序默认端口号:tomcat:8080、mysqp:3306、oracle:1521、sqlserver:1433
  5. netstat -an|more可查看当前主机网络情况,包括端口监听与网络连接
  6. netstat -anb查看网络情况,同时显示使用端口的对应程序
InetAddress类

概述:Java提供了InetAddress类来代表IP地址,InetAddress下还有两个子类:Inet4Address、Inet6Address。

获取实例对象:

public static InetAddress getLocalHost()
//返回本地主机的InetAddress对象。 
public static InetAddress getByName(String host)
//根据提供的主机名和IP地址创建InetAddress对象。
public static InetAddress getByAddress(byte[] addr) 
//根据提供的原始IP地址创建InetAddress对象。  

常用方法:

public String getHostName() 
//获取此IP地址的主机名。  
public String getHostAddress() 
//返回文本显示中的IP地址字符串。  
public byte[] getAddress() 
//返回此InetAddress对象的原始IP地址。 
ServerSocket类

概述:这个类实现了服务器套接字。 服务器套接字等待通过网络进入的请求。ServerSocket对象就代表服务器端程序。

构造方法:

ServerSocket(int port);
//创建绑定到指定端口的服务器套接字。
ServerSocket(int port, int backlog) 
//创建服务器套接字并将其绑定到指定的本地端口号,并指定了连接请求的最大队列长度。

核心方法:

Socket accept() 
//等待客户端连接并获得与客户端关联的Socket对象。
void close() 
//关闭此套接字。 
InetAddress getInetAddress() 
//返回此服务器套接字的本地地址。
int getLocalPort() 
//返回此套接字正在侦听的端口号。  
Socket类

概述: Socket开发网络程序被广泛应用,通信两端都要有Socket,相对于是两台机器通信的端点。Socket允许程序把网络连接当成一个流,数据在两个Socket间通过IO传输。TCP网络通讯时当客户端连接服务端后,实际上客户端也是通过一个端口和服务端进行通讯的,该端口号是由TCP/IP随机分配的。

构造方法:

public Socket(String host, int port);
//根据ip地址字符串和端口号创建客户端Socket对象
public Socket(InetAddress address,int port);
//创建流套接字并将其连接到指定IP地址的指定端口号。

核心方法:

OutputStream getOutputStream(); 
// 获得字节输出流对象
InputStream getInputStream(); 
// 获得字节输入流对象
InetAddress getInetAddress();
//返回套接字所连接的地址,若未连接返回null
InetAddress getLocalAddress();
//获取套接字所绑定的本地地址,若套接字关闭或未绑定,则为通配符地址。
int getPort() 
//返回此套接字连接到的远程端口号。 
TCP通讯案例
//基于TCP通信-服务端
public static void main(String[] args) throws IOException {
    ServerSocket serverSocket = new ServerSocket(9888);
    System.out.println("服务端服务已开启~~~");
    Socket server = serverSocket.accept();
    //阻塞等待客户端接入
    InputStream IS = server.getInputStream();
    BufferedInputStream BIS = new BufferedInputStream(IS);
    OutputStream OS = server.getOutputStream();
    BufferedOutputStream BOS = new BufferedOutputStream(OS);
    byte[] arr = new byte[50];
    int location = -1;
    StringBuffer clientinformation = new StringBuffer();
    while ((location = BIS.read(arr)) != -1) {
        clientinformation.append(new String(arr, 0, location));
    }//读客户端发送消息,输出控制台
    String information = clientinformation.toString();
    if ("你好服务端,我来下载文件".equals(information)) {
        byte[] fileArr = FileUtils.readFileToByteArray(
                new File("Day12\\src\\com\\lxl\\homework\\stu.txt"));
        //利用commons-io工具将文件转换字节文件
        BOS.write(fileArr);
        BOS.flush();
        server.shutdownOutput();
    } else {
        BOS.write("该请求无法理解".getBytes());
        BOS.flush();
        server.shutdownOutput();
    }
    System.out.println("服务端响应完毕");
    BOS.close();
    BIS.close();
    server.close();
}
public static void main(String[] args) throws IOException {
    Socket client = new Socket("127.0.0.1", 9888);
    OutputStream OS = client.getOutputStream();
    //获取socket套接字的输出流对象
    BufferedOutputStream BOS = new BufferedOutputStream(OS);
    //为了提高文件输出效率,使用包装流代理原本的socket的字节流
    BOS.write("你好服务端,我来下载文件".getBytes());
    BOS.flush();
    //确保包装流的缓冲区内容全部写出,否则可能造成传输内容不全面
    client.shutdownOutput();
    //写出结束标识,底层关闭socket输出流,告诉服务端:客户端写出结束
    //因为包装类的缓冲区buf在BOS对象上,而shutdowOutput()关闭OS流
    //即绕过了BOS的flushBuffer()没将缓冲区内容写出
    //所以务必在shutdown()前调用包装流的flush(),否则可能传输内容丢失!!!
    InputStream IS = client.getInputStream();
    BufferedInputStream BIS = new BufferedInputStream(IS);
    ByteArrayOutputStream BAOS = new ByteArrayOutputStream();
    //定义BAOS来存储每次读取文件字节
    byte[] fileArr = new byte[1024];
    int location = -1;
    while ((location = BIS.read(fileArr)) != -1) {
        BAOS.write(fileArr, 0, location);
    }
    FileUtils.writeByteArrayToFile(new File("Server_"
            + new Random().nextInt() + ".txt"), BAOS.toByteArray());
    //利用commons-io工具将文件字节数组写出为文件
    System.out.println("已接收文件,完成传输~");
    BOS.close();
    BIS.close();
    client.close();
}
UDP网络编程

概述:类DatagramSocketDatagramPacket实现了基于UDP协议网络程序,UDP数据报通过数据报套接字DatagramSocket发送和接受,系统不保证数据报安全稳定送达,也不确定送达时间。UDP协议中每个数据报都给出了完整地址信息,因此无需建立两端连接

DatagramSocket类:

//构造器:
publicDatagramSocket() 
//构造数据报套接字并将其绑定到本地主机上的任何可用端口
DatagramSocket(int port) 
//构造数据报套接字并将其绑定到本地主机上的指定端口。  
DatagramSocket(int port, InetAddress laddr) 
//创建一个数据报套接字,绑定到指定的本地地址。  

//常用方法:
void close() 
//关闭此数据报套接字。  
void connect(InetAddress address, int port) 
//将套接字连接到此套接字的远程地址。  
InetAddress getLocalAddress() 
//获取套接字所绑定的本地地址。  
int getLocalPort() 
//返回此套接字绑定到的本地主机上的端口号。  
InetAddress getInetAddress() 
//返回此套接字连接到的地址。  
void receive(DatagramPacket p) 
//从此套接字接收数据报包。  
void send(DatagramPacket p) 
//从此套接字发送数据报包。  
boolean isClosed() 
//返回套接字是否关闭。  
boolean isConnected() 
//返回套接字的连接状态。  

DatagramPacket类:

//构造器:
DatagramPacket(byte[] buf, int length, InetAddress address, int port) 
//构造用于发送/接收length长度的分组数据报包,指定主机上到指定的端口号。  
DatagramPacket(byte[] buf, int offset, int length) 
//构造用于发送/接收偏移offset的length长度的分组数据报包。
DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port) 
//构造用于发送/接收偏移offset的length长度的分组数据报包,指定主机上到指定的端口号。  
DatagramPacket(byte[] buf, int length) 
//构造用于发送/接收length长度的分组数据报包。

//常用方法:
byte[] getData() 
//返回数据缓冲区。  
int getLength() 
//返回要发送的数据的长度或接收到的数据的长度。  
int getOffset() 
//返回要发送的数据的偏移量或接收到的数据的偏移量。  
int getPort() 
//返回发送数据报的远程主机上的端口号,或从中接收数据报的端口号。  
void setAddress(InetAddress iaddr) 
//设置该数据报发送到的机器的IP地址。  
void setData(byte[] buf) 
//设置此数据包的数据缓冲区。  
void setLength(int length) 
//设置此数据包的长度。  
void setPort(int iport) 
//设置发送此数据报的远程主机上的端口号。  

UDP通信实例:

/*基本流程:
* 1. 建立发送端、接收端(无服务端、客户端概念)
* 2. 发送数据前,建立数据报DatagramPacket对象(装包)
* 3. 调用DatagramSocket套接字对象的发送send、接收receive方法
* 4. 接收端等待接收数据报,接收完毕后需拆包使用
* 5. 关闭DatagramSocket对象
*/

//基于UDP的网络编程-接收端
DatagramSocket socket = new DatagramSocket(9998);
//创建在9998端口接受数据的DatagramSocket对象
byte[] arr = new byte[1024*10];//UDP数据报最大64K
DatagramPacket packet = new DatagramPacket(arr, arr.length);
//创建接受数据报的DatagramPacket对象
socket.receive(packet);//阻塞等待数据报
//接收数据报,并填充如DatagramPacket对象
int length = packet.getLength();//获取数据报数据字节数组长度
byte[] data = packet.getData();
//获取数据字节数组,本质上返回作为缓冲区的arr
String message = new String(data, 0, length);
System.out.println(message);
socket.close();

//基于UDP的网络编程-发送端
DatagramSocket socket = new DatagramSocket(9996);
//创建在9996端口接收数据的DatagramSocket对象
byte[] arr = "今晚去嗨呀~".getBytes();//数组字节数组
DatagramPacket packet = new DatagramPacket(arr, arr.length, 				InetAddress.getByName("127.0.0.1"), 9998
);
//创建发送的数据报,封装数据字节数组,数组长度,目的主机ip对象,端口号
socket.send(packet);//发送数据报
socket.close();

反射机制

Refletion体系

反射获取类成员
//访问方法
//1.根据方法名和参数列表获取Method对象(任意修饰权限)
//getDeclareMethod(方法名,Class...classes)
Method m = catclass.getDeclareMethod("eat"String.class);
//2.创建类的实例对象
Object cat = catclass.newInstance();
//3.爆破方法
m.setAccessible(true);
//4.调用方法
m.invoke(cat,"I am cat");
//调用静态方法,invoke方法的第一个参数可为null

//访问构造器
//1.获取该类的Class对象
Class catclass = Class.forName("com.lxl.Cat");
//2.获取该Class的private修饰有参、无参构造器
Constructor constructor = catclass.getDeclareConstructor(String.class, int.class);
//3.创建实例,并传入参数(爆破)
constructor.setAccessible(true);
//关闭访问安全检查,爆破
Object cat = constructor.newInstancs("LXL", 1);
类加载器读取配置
//通过Classloader类加载器的流读取配置文件
Properties pros = new Properties();
ClassLoader classloader = Test.class.getClassLoader();
//Test为所在类类名
InputStream in = classloader.getResourAsStream("xxx.properties");
pros.load(in);

注解

基本注解

概述:

  1. 注解是JDK1.5的新特性,又称元数据,用于修饰解释包、类、方法、属性、构造器、局部变量等数据信息
  2. 不影响代码逻辑,但注解可以被编译运行
  3. 标记过时功能,忽略警告等,JavaEE中注解可用来配置应用程序的切面,替代旧版中遗留的繁多代码和XML配置
  4. 注解相当一种标记,是类的组成部分,可以给类携带一些额外的信息。
  • 注解是给机器(jvm)看的,编译器或JVM可以根据注解来完成对应的功能;而注释是给人(程序员)看的!

基本注解:

  1. @Override:限定某个方法是重写父类方法,只可用于方法
  2. @Deprecated:用于表示某个程序元素已过时
  3. @SuppressWarnings:抑制编译器警告
  4. @author:标记作者
  5. @version:用于标识对象的版本号,适用范围:文件、类、方法。
元注解
  1. @Retention指定注解作用范围(RetentionPolicy枚举类)
    • SOURCE:源码级别保留,编译后即丢弃。
    • CLASS:编译级别保留,编译后的class文件中存在,在jvm运行时丢弃,这是默认值。
    • RUNTIME:运行级别保留,编译后的class文件中存
  2. @Target指定注解可以在那些地方使用(ElementType枚举类)
    • ANNOTATION_TYPE:作用在注解上,Target修饰的目标注解B,可用来修饰注解C。
    • CONSTRUCTOR:作用在构造方法上
    • FIELD:作用在变量属性字段上。
    • LOCAL_VARIABLE:作用在局部变量声名上。
    • METHOD:作用在方法上
    • PACKAGE:作用在包名上。
    • PARAMETER:作用在参数上
    • TYPE:任何类型,即上面的类型都可以修饰
  3. @Documented指定注解是否会在javadoc体现
  4. @Inherited子类会继承父类注解
自定义注解

注解本质:

//@SuppressWarnings注解的源代码,发现注解其本质就是一个接口!
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
 /** 这里有很多的注释 */
 String[] value(); // 注解的属性!
}

自定义注解格式:

@Target(ElementType.METHOD)//表示可以修饰任何类型
@Retention(RetentionPolicy.RUNTIME)//该注解运行时可见
public @interface 注解名{
	// 里面定义属性即可
 //格式1:数据类型 属性名() default 默认值;
 //格式2:数据类型 属性名();
 String[] value();
}

/*
* 属性适用的数据类型
* 八种数据数据类型(int,short,long,double,byte,char,boolean,float)
* String,Class,注解类型,枚举类
* 以上类型的一维数组形式
*/

自定义注解使用:

public @interface Book {
    // 为注解定义属性
    String value() default "vip";	
}

@Book("xxx")  // 此处可以写成 @Book(value="xxxx"),还可以省略属性名称value不写 
public void method(){}

综合案例:

@PeopleInformation(name = "韦小宝", age = 28, isMarry = true, my = @MyTest)
public class People {
    private String name;
    private Integer age;
    private boolean isMarray;
}

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface PeopleInformation {
    String name() default "无名氏";
    int age() default 18;
    boolean isMarry() default false;
    MyTest my();
}

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTest {
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值