java基础-Java网络编程和反射


一、网络编程

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

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

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

TCP: TCP是传输控制协议的缩写,它保障了两个应用程序之间的可靠通信。通常用于互联网协议,被称TCP / IP。

UDP:UDP是用户数据报协议的缩写,一个无连接的协议。提供了应用程序之间要发送的数据的数据包。

2、网络参考模型


3、Socket 编程

套接字使用TCP提供了两台计算机之间的通信机制。 客户端程序创建一个套接字,并尝试连接服务器的套接字。

当连接建立时,服务器会创建一个Socket对象。客户端和服务器现在可以通过对Socket对象的写入和读取来进行进行通信。

java.net.Socket类代表一个套接字,并且java.net.ServerSocket类为服务器程序提供了一种来监听客户端,并与他们建立连接的机制。

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

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

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

(3)服务器正在等待时,一个客户端实例化一个Socket对象,指定服务器名称和端口号来请求连接。Socket类的构造函数试图将客户端连接到指定的服务器和端口号。如果通信被建立,则在客户端创建一个Socket对象能够与服务器进行通信。

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

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

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

/*
需求:上传图片。
*/
/*
客户端。
1,服务端点。
2,读取客户端已有的图片数据。
3,通过socket 输出流将数据发给服务端。
4,读取服务端反馈信息。
5,关闭。
*/

import java.io.*;
import java.net.*;
class  PicClient
{
	public static void main(String[] args)throws Exception 
	{
		Socket s = new Socket("192.168.1.254",10007);

		FileInputStream fis = new FileInputStream("c:\\1.bmp");

		OutputStream out = s.getOutputStream();

		byte[] buf = new byte[1024];

		int len = 0;

		while((len=fis.read(buf))!=-1)
		{
			out.write(buf,0,len);
		}

		//告诉服务端数据已写完
		s.shutdownOutput();

		InputStream in = s.getInputStream();

		byte[] bufIn = new byte[1024];

		int num = in.read(bufIn);
		System.out.println(new String(bufIn,0,num));

		fis.close();
		s.close();
	}
}

/*
服务端
*/
class  PicServer
{
	public static void main(String[] args) throws Exception
	{
		ServerSocket ss = new ServerSocket(10007);

		Socket s = ss.accept();

		InputStream in = s.getInputStream();

		FileOutputStream fos = new FileOutputStream("server.bmp");

		byte[] buf = new byte[1024];

		int len = 0;
		while((len=in.read(buf))!=-1)
		{
			fos.write(buf,0,len);
		}

		OutputStream out = s.getOutputStream();

		out.write("上传成功".getBytes());

		fos.close();

		s.close();

		ss.close();
	}
}


u  服务端编写步骤:
1.利用ServerSocket建立对服务端某个端口的监听。
                     如:ServerSocket  server = new ServerSocket(8000);
2.利用accept方法创建服务端Socket
                     如:Socket socket = server.accept()
3.利用已建立的socket创建输入输出流
                     如:BufferedReader br = new      BufferedReader( newInputStreamReader(   socket.getInputStream()));
      BufferedWriter pw = new BufferedWriter(newOutputStreamWriter(socket.getOutputStream()));
4.关闭输入输出流,关闭socket,关闭server
                     如:       br.close();     
                                   pw.close();
                                   socket.close();
 
u  客户端编写步骤:
1.创建客户端Socket向服务器发起连接请求
                     如:Socket  socket = new Socket (“127.0.0.1”, 8000);
2..利用已建立的socket创建输入输出流
         如:BufferedReader br = new BufferedReader
              (  newInputStreamReader( ket.getInputStream()));
                BufferedWriter pw = new BufferedWriter                                               (newOutputStreamWriter(socket.getOutputStream()));
3.关闭输入输出流,关闭socket,关闭server
                     如:       br.close();   
二、反射
1、反射的概念和由来
     Java反射机制是在运行状态中,对于任意一个,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。
2、反射的特点
2.1、在运行时判断任意一个对象所属的类
2.2、在运行时构造任意一个类的对象
2.3、在运行时判断任意一个类所具有的成员变量和方法
2.4、在运行时调用任意一个对象的方法
通过一个例子来理解Java的反射机制是如何工作的
import java.lang.reflect.Method;

/**
 * Java 反射练习。
 * 
 * 
 */
public class ForNameTest {

    /**
     * 入口函数。
     * 
     * @param args
     *            参数
     * @throws Exception
     *             错误信息
     */
    public static void main(String[] args) throws Exception {
        // 获得Class
        Class<?> cls = Class.forName(args[0]);
        // 通过Class获得所对应对象的方法
        Method[] methods = cls.getMethods();
        // 输出每个方法名
        for (Method method : methods) {
            System.out.println(method);
        }
    }
}

使用java的反射机制,一般需要遵循三步:

1、获得你想操作类的Class对象

2、通过第一步获得的Class对象去取得操作类的方法或是属性名操作

3、第二步取得的方法或是属性java运行的时候,某个类无论生成多少个对象,他们都会对应同一个Class对象,它表示正在运行程序中的类和接口。如何取得操作类的Class对象,常用的有三种方式:

1、调用Class的静态方法forName,如上例;

2、使用类的.class语法,如:Class<?> cls = String.class;

3、调用对象的getClass方法,如:String str = "abc";Class<?> cls = str.getClass();

import java.lang.reflect.Field;
 4 
 5 /**
 6  * Java 反射之属性练习。
 7  * 
 8  * @author Wanggc
 9  */
10 public class ReflectionTest {
11     public static void main(String[] args) throws Exception {
12         // 建立学生对象
13         Student student = new Student();
14         // 为学生对象赋值
15         student.setStuName("Wanggc");
16         student.setStuAge(24);
17         // 建立拷贝目标对象
18         Student destStudent = (Student) copyBean(student);
19         // 输出拷贝结果
20         System.out.println(destStudent.getStuName() + ":"
21                 + destStudent.getStuAge());
22     }
23 
24     /**
25      * 拷贝学生对象信息。
26      * 
27      * @param from
28      *            拷贝源对象
29      * @param dest
30      *            拷贝目标对象
31      * @throws Exception
32      *             例外
33 */
34     private static Object copyBean(Object from) throws Exception {
35         // 取得拷贝源对象的Class对象
36         Class<?> fromClass = from.getClass();
37         // 取得拷贝源对象的属性列表
38         Field[] fromFields = fromClass.getDeclaredFields();
39         // 取得拷贝目标对象的Class对象
40         Object ints = fromClass.newInstance();
41         for (Field fromField : fromFields) {
42             // 设置属性的可访问性
43             fromField.setAccessible(true);
44             // 将拷贝源对象的属性的值赋给拷贝目标对象相应的属性
45             fromField.set(ints, fromField.get(from));
46         }
47 
48         return ints;
49     }
50 }
51 
52 /**
53  * 学生类。
54  */
55 class Student {
56     /** 姓名 */
57     private String stuName;
58     /** 年龄 */
59     private int stuAge;
60 
61     /**
62      * 获取学生姓名。
63      * 
64      * @return 学生姓名
65 */
66     public String getStuName() {
67         return stuName;
68     }
69 
70     /**
71      * 设置学生姓名
72      * 
73      * @param stuName
74      *            学生姓名
75 */
76     public void setStuName(String stuName) {
77         this.stuName = stuName;
78     }
79 
80     /**
81      * 获取学生年龄
82      * 
83      * @return 学生年龄
84 */
85     public int getStuAge() {
86         return stuAge;
87     }
88 
89     /**
90      * 设置学生年龄
91      * 
92      * @param stuAge
93      *            学生年龄
94 */
95     public void setStuAge(int stuAge) {
96         this.stuAge = stuAge;
97     }
98 }






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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值