网络编程、反射

一、网络编程

  1. Socket编程

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

2Socket,实际上是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket,我们才能使用TCP/IP协议。

3)TCP/IP只是一个协议栈,就像操作系统的运行机制一样,必须要具体实现,同时还要提供对外的操作接口。这个就像操作系统会提供标准的编程接口,比如win32编程接口一样,TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口。

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

2、Socket整体流程

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

客户端请求与服务器进行连接的时候,根据服务器的域名或者IP地址,加上端口号,打开一个套接字。当服务器接受连接后,服务器和客户端之间的通信就像输入输出流一样进行操作。

3、ServerSocket 类的方法

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

方法

方法描述

public ServerSocket(int port) throws IOException

创建绑定到特定端口的服务器套接字。

public ServerSocket(int port, int backlog) throws IOException

利用指定的 backlog 创建服务器

套接字并将其绑定到指定的本地

端口号。

public ServerSocket(int port, int backlog, InetAddress address) throws IOException

使用指定的端口、侦听 backlog

和要绑定到的本地 IP 地址创建服务器。

public ServerSocket() throws IOException

创建非绑定服务器套接字。

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

这里有一些 ServerSocket 类的常用方法:

方法

方法描述

public int getLocalPort()

返回此套接字在其上侦听的端口。

public Socket accept() throws IOException

侦听并接受到此套接字的连接。

public void setSoTimeout(int timeout)

通过指定超时值启用/禁用 SO_TIMEOUT,

以毫秒为单位。

public void bind(SocketAddress host, int backlog)

将 ServerSocket 绑定到特定地址(IP 地址和端口号)。


4、Socket 类的方法

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

Socket 类有五个构造方法.

方法

方法描述

public Socket(String host, int port) throws UnknownHostException, IOException.

创建一个流套接字并将其连接到指定

主机上的指定端口号。

public Socket(InetAddress host, int port) throws IOException

创建一个流套接字并将其连接到指定

 IP 地址的指定端口号。

public Socket(String host, int port, InetAddress localAddress, int localPort) throws IOException.

创建一个套接字并将其连接到指定远

程主机上的指定远程端口。

public Socket(InetAddress host, int port, InetAddress localAddress, int localPort) throws IOException.

创建一个套接字并将其连接到指定远

程地址上的指定远程端口。

public Socket()

通过系统默认类型的 SocketImpl

创建未连接套接字

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

下面列出了一些感兴趣的方法,注意客户端和服务器端都有一个 Socket 对象,所以无论客户端还是服务端都能够调用这些方法。

方法

方法描述

public void connect(SocketAddress host, int timeout) throws IOException

将此套接字连接到服务器,并指定一个超时值。

public InetAddress getInetAddress()

返回套接字连接的地址。

public int getPort()

返回此套接字连接到的远程端口。

public int getLocalPort()

返回此套接字绑定到的本地端口。

public SocketAddress getRemoteSocketAddress()

返回此套接字连接的端点的地址,如果

未连接则返回 null。

public InputStream getInputStream() throws IOException

返回此套接字的输入流。

public OutputStream getOutputStream() throws IOException

返回此套接字的输出流。

public void close() throws IOException

关闭此套接字。


  1. 服务端实例

public class Server {

    private ServerSocket server;

    public Server(){

        try {

            System.out.println("正在启动服务器....");

            server = new ServerSocket(8082);

            System.out.println("服务器启动成功");

        } catch (Exception e) {

            System.out.println("服务器启动失败");

            e.printStackTrace();

        }

    }

    public void start(){

        System.out.println("等待客户端建立连接....");

        try {

            Socket socket = server.accept();

            System.out.println("一个客户端连接成功");

            InputStream inputStream = socket.getInputStream();

            InputStreamReader isr = new InputStreamReader(inputStream, "utf-8");

            BufferedReader br = new BufferedReader(isr);

            while (true){

                String result = br.readLine();

                System.out.println("客户端说:" + result);

                Thread.sleep(30000);

            }

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

    public static void main(String[] args) {

        Server server = new Server();

        server.start();

    }

  1. 客户端实例

public class Client {

    private Socket socket;

    public Client(){

        try {

            System.out.println("正在与服务器建立连接....");

            socket = new Socket("localhost", 8082);

            System.out.println("连接服务器成功");

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

    public void start(){

        try {

            OutputStream outputStream = socket.getOutputStream();

            OutputStreamWriter osw = new OutputStreamWriter(outputStream, "utf-8");

            BufferedWriter bw = new BufferedWriter(osw);

            PrintWriter w = new PrintWriter(bw, true);

            w.println("你好");

            w.close();

            socket.close();

        } catch (IOException e) {

            e.printStackTrace();

        }

    }

    public static void main(String[] args) {

        Client c = new Client();

        c.start();

    }

二、反射

  1. 概论

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

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

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

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

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

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

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

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

5)生成动态代理。

3、Java 反射机制的优缺点

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

缺点:

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

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

4、通过反射访问构造方法

为了能够动态获取对象构造方法的信息,首先需要通过下列方法之一创建一个 Constructor 类型的对象或者数组。 ​

getConstructors() ​

getConstructor(Class<?>…parameterTypes) ​

getDeclaredConstructors() ​

getDeclaredConstructor(Class<?>...parameterTypes)

如果是访问指定的构造方法,需要根据该构造方法的入口参数的类型来访问。例如,访问一个入口参数类型依次为 int 和 String 类型的构造方法,下面的两种方式均可以实现。

objectClass.getDeclaredConstructor(int.class,String.class);

objectClass.getDeclaredConstructor(new Class[]{int.class,String.class});

创建的每个 Constructor 对象表示一个构造方法,然后利用 Constructor 对象的方法操作构造方法。

  1. 通过反射访问构造方法

要动态获取一个对象方法的信息,首先需要通过下列方法之一创建一个 Method 类型的对象或者数组。 ​

 getMethods() ​

getMethods(String name,Class<?> …parameterTypes) ​

getDeclaredMethods() ​

getDeclaredMethods(String name,Class<?>...parameterTypes)

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

下面的两种方式均可以实现:

objectClass.getDeclaredConstructor("max",int.class,String.class);

objectClass.getDeclaredConstructor("max",new Class[]{int.class,String.class});

  1. 通过反射访问成员变量

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

上述方法返回的 Field 对象代表一个成员变量。例如,要访问一个名称为 price 的成员变量,示例代码如下:

object.getDeciaredField("price");

方法名称

说明

getName()

获得该成员变量的名称

getType()

获取表示该成员变量的 Class 对象

get(Object obj)

获得指定对象 obj 中成员变量的值,返回值为 Object 类型

set(Object obj, Object value)

将指定对象 obj 中成员变量的值设置为 value

getlnt(0bject obj)

获得指定对象 obj 中成员类型为 int 的成员变量的值

setlnt(0bject obj, int i)

将指定对象 obj 中成员变量的值设置为 i

setFloat(Object obj, float f)

将指定对象 obj 中成员变量的值设置为 f

getBoolean(Object obj)

获得指定对象 obj 中成员类型为 boolean 的成员变量的值

setBoolean(Object obj, boolean b)

将指定对象 obj 中成员变量的值设置为 b

getFloat(Object obj)

获得指定对象 obj 中成员类型为 float 的成员变量的值

setAccessible(boolean flag)

此方法可以设置是否忽略权限直接访问 private 等私有权限

的成员变量

getModifiers()

获得可以解析出该方法所采用修饰符的整数

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值