JAVA_初级网络编程

Socket

一、Java 网络编程

              网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来。

              java.net 包中 J2SE 的 API 包含有类和接口,它们提供低层次的通信细节。你可以直接使用这些类和接口,来专注于解决问题,而不用关注通信细节。

java.net 包中提供了两种常见的网络协议的支持:

TCP:TCP(英语:Transmission Control Protocol,传输控制协议) 是一种面向连接的、可靠的、基于字节流的传输层通信协议,TCP 层是位于 IP 层之上,应用层之下的中间层。TCP 保障了两个应用程序之间的可靠通信。通常用于互联网协议,被称 TCP / IP。

UDP:UDP (英语:User Datagram Protocol,用户数据报协议),位于 OSI 模型的传输层。一个无连接的协议。提供了应用程序之间要发送数据的数据报。由于UDP缺乏可靠性且属于无连接协议,所以应用程序通常必须容许一些丢失、错误或重复的数据包。

 Socket 编程

​              套接字使用TCP提供了两台计算机之间的通信机制。 客户端程序创建一个套接字,并尝试连接服务器的套接字。当连接建立时,服务器会创建一个 Socket 对象。客户端和服务器现在可以通过对 Socket 对象的写入和读取来进行通信。java.net.Socket 类代表一个套接字,并且 java.net.ServerSocket 类为服务器程序提供了一种来监听客户端,并与他们建立连接的机制。

​              以下步骤在两台计算机之间使用套接字建立TCP连接时会出现:

​                            1、服务器实例化一个 ServerSocket 对象,表示通过服务器上的端口通信。

​                            2、服务器调用 ServerSocket 类的 accept() 方法,该方法将一直等待,直到客户端连接到服务器上给定的端口。

​                            3、服务器正在等待时,一个客户端实例化一个 Socket 对象,指定服务器名称和端口号来请求连接。

​                            4、Socket 类的构造函数试图将客户端连接到指定的服务器和端口号。如果通信被建立,则在客户端创建一个 Socket 对象能够       与服务器进行通信。

​                            5、在服务器端,accept() 方法返回服务器上一个新的 socket 引用,该 socket 连接到客户端的 socket。

​              连接建立后,通过使用 I/O 流在进行通信,每一个socket都有一个输出流和一个输入流,客户端的输出流连接到服务器端的输入流,而客户端的输入流连接到服务器端的输出流。

​              TCP 是一个双向的通信协议,因此数据可以通过两个数据流在同一时间发送.以下是一些类提供的一套完整的有用的方法来实现 socket。

​              Java的网络编程主要涉及到的内容是Socket编程。

## Socket整体流程

​              Socket编程主要涉及到客户端和服务端两个方面,首先是在服务器端创建一个服务器套接字(ServerSocket),并把它附加到一个端口上,服务器从这个端口监听连接。端口号的范围是0到65536,但是0到1024是为特权服务保留的端口号,我们可以选择任意一个当前没有被其他进程使用的端口。

ServerSocket 类的方法

              服务器应用程序通过使用 java.net.ServerSocket 类以获取一个端口,并且侦听客户端请求。

创建非绑定服务器套接字。 如果 ServerSocket 构造方法没有抛出异常,就意味着你的应用程序已经成功绑定到指定的端口,并且侦听客户端请求。

 Socket 类的方法

​              java.net.Socket 类代表客户端和服务器都用来互相沟通的套接字。客户端要获取一个 Socket 对象通过实例化 ,而 服务器获得一个 Socket 对象则通过 accept() 方法的返回值。

Socket 构造方法返回,并没有简单的实例化了一个 Socket 对象,它实际上会尝试连接到指定的服务器和端口。

InetAddress 类的方法

              这个类表示互联网协议(IP)地址。

Socket 客户端实例

​              如下的 GreetingClient 是一个客户端程序,该程序通过 socket 连接到服务器并发送一个请求,然后等待一个响应。

Socket 服务端实例

​              如下的GreetingServer 程序是一个服务器端应用程序,使用 Socket 来监听一个指定的端口。

反射

一、反射概念

              Java 反射机制是 Java 语言的一个重要特性。在学习 Java 反射机制前,先了解两个概念,编译期运行期

              编译期是指把源码交给编译器编译成计算机可以执行的文件的过程。在 Java 中也就是把 Java 代码编成 class 文件的过程。编译期只是做了一些翻译功能,并没有把代码放在内存中运行起来,而只是把代码当成文本进行操作,比如检查错误。

              运行期是把编译后的文件交给计算机执行,直到程序运行结束。所谓运行期就把在磁盘中的代码放到内存中执行起来。

              Java 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为 Java 语言的反射机制。简单来说,反射机制指的是程序在运行时能够获取自身的信息。在 Java 中,只要给定类的名字,就可以通过反射机制来获得类的所有信息。

              Java 反射机制在服务器程序和中间件程序中得到了广泛运用。在服务器端,往往需要根据客户的请求,动态调用某一个对象的特定方法。此外,在 ORM 中间件的实现中,运用 Java 反射机制可以读取任意一个 JavaBean 的所有属性,或者给这些属性赋值。

Java 反射机制主要提供了以下功能,这些功能都位于java.lang.reflect包。

​                            1、在运行时判断任意一个对象所属的类。

​                            2、在运行时构造任意一个类的对象。

​                            3、在运行时判断任意一个类所具有的成员变量和方法。

​                            4、在运行时调用任意一个对象的方法。

​                            5、生成动态代理。

​              要想知道一个类的属性和方法,必须先获取到该类的字节码文件对象。获取类的信息时,使用的就是 Class 类中的方法。所以先要获取到每一个字节码文件(.class)对应的 Class 类型的对象.

​              众所周知,所有 Java 类均继承了 Object 类,在 Object 类中定义了一个 getClass() 方法,该方法返回同一个类型为 Class 的对象。

Java 反射机制的优缺点

优点:          能够运行时动态获取类的实例,大大提高系统的灵活性和扩展性。          Java 动态编译相结合,可以实现无比强大的功能。            对于 Java 这种先编译再运行的语言,能够让我们很方便的创建灵活的代码,这些代码可以在运行时装配,无需在组件之间进行源代码的链接,更加容易实现面向对象。

缺点:

              反射会消耗一定的系统资源,因此,如果不需要动态地创建一个对象,那么就不需要用反射;          反射调用方法时可以忽略权限检查,获取这个类的私有方法和属性,因此可能会破坏类的封装性而导致安全问题。

Java 反射机制在一般的 Java 应用开发中很少使用,即便是 Java EE 阶段也很少使用。

二、反射机制API

              实现 Java 反射机制的类都位于 java.lang.reflect 包中,java.lang.Class 类是 Java 反射机制 API 中的核心类。

1java.lang.Class

              java.lang.Class 类是实现反射的关键所在,Class 类的一个实例表示 Java 的一种数据类型,包括类、接口、枚举、注解(Annotation)、数组、基本数据类型和 voidClass 没有公有的构造方法,Class 实例是由 JVM 在类加载时自动创建的。

ava.lang.reflect

java.lang.reflect 包提供了反射中用到类,主要的类说明如下:

Constructor 类:提供类的构造方法信息。

Field 类:提供类或接口中成员变量信息。

Method 类:提供类或接口成员方法信息。

Array 类:提供了动态创建和访问 Java 数组的方法。

Modifier 类:提供类和成员访问修饰符信息。

通过反射访问构造方法

              为了能够动态获取对象构造方法的信息,首先需要通过下列方法之一创建一个 Constructor 类型的对象或者数组。                           getConstructors()                           getConstructor(Class<?>…parameterTypes)                           getDeclaredConstructors()                          getDeclaredConstructor(Class<?>...parameterTypes)

              如果是访问指定的构造方法,需要根据该构造方法的入口参数的类型来访问。

       通过 java.lang.reflect.Modifier 类可以解析出 getMocMers() 方法的返回值所表示的修饰符信息。在该类中提供了一系列用来解析的静态方法,既可以查看是否被指定的修饰符修饰,还可以字符串的形式获得所有修饰符。

通过反射执行方法

              动态获取一个对象方法的信息,首先需要通过下列方法之一创建一个 Method 类型的对象或者数组。                           getMethods()                           getMethods(String name,Class<?> …parameterTypes)                         getDeclaredMethods()                          getDeclaredMethods(String name,Class<?>...parameterTypes)

              如果是访问指定的构造方法,需要根据该方法的入口参数的类型来访问。例如,访问一个名称为 max,入口参数类型依次为 int String 类型的方法。

通过反射访问成员变量

              通过下列任意一个方法访问成员变量时将返回 Field 类型的对象或数组。                           getFields()                         getField(String name)                            getDeclaredFields()                        getDeclaredField(String name)

              上述方法返回的 Field 对象代表一个成员变量。

获取继承关系

              当我们获取到某个Class对象时,实际上就获取到了一个类的类型:

Class cls = String.class; // 获取到StringClass

              还可以用实例的getClass()方法获取:

String s = "";
Class cls = s.getClass(); // sString,因此获取到StringClass

              最后一种获取Class的方法是通过Class.forName(""),传入Class的完整类名获取:

Class s = Class.forName("java.lang.String");

              这三种方式获取的Class实例都是同一个实例,因为JVM对每个加载的Class只创建一个Class实例来表示它的类型。

通过Class对象可以获取继承关系:

Class getSuperclass():获取父类类型;

Class[] getInterfaces():获取当前类实现的所有接口。

通过Class对象的isAssignableFrom()方法可以判断一个向上转型是否可以实现。

# 动态代理

我们来比较Java的`class`和`interface`的区别:

- 可以实例化`class`(非`abstract`);

- 不能实例化`interface`。

所有`interface`类型的变量总是通过某个实例向上转型并赋值给接口类型变量的

              1、定义一个InvocationHandler实例,它负责实现接口的方法调用;

​                            2、通过Proxy.newProxyInstance()创建interface实例,它需要3个参数:

​                                          2.1、使用的ClassLoader,通常就是接口类的ClassLoader;

​                                          2.2、需要实现的接口数组,至少需要传入一个接口进去;

​                                          2.3、用来处理接口方法调用的InvocationHandler实例。

​                            3、将返回的Object强制转型为接口。

小结

              Java标准库提供了动态代理功能,允许在运行期动态创建一个接口的实例;

              动态代理是通过Proxy创建代理对象,然后将接口方法代理InvocationHandler完成的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值