声明:由于学习所用环境为JDK1.8,所有java代码均在JDK1.8环境中测试通过,如果环境发生改变,可能会有错误发生!
一、UDP网络编程
1、(1)面向无连接的数据传输,不可靠的,但效率高
音频、视频、…
(2)UDP一次发送的数据不能超过64KB.
(3)UDP编程所需要的类
DatagramSocket 此类表示用来发送和接收数据报包的套接字
DatagramPacket 此类表示数据报包
DatagramPacket(byte[] buf, int length, InetAddress address, int port)
buf - 包数据
length - 包长度
address - 目的地址
port - 目的端口号
2、DatagramSocket常用方法
构造方法:
public DatagramSocket(int port)
常用方法:
public void send(DatagramPacket p) 发送数据报包
public void receive(DatagramPacket p) 接收数据报包
构造方法:
public DatagramPacket(byte[] buf, int length)此构造方法用来接收数据
public DatagramPacket(byte[] buf, int length, InetAddress address, int port) 此构造方法用来组装将要发送的数据
1. public InetAddress getAddress()
返回将要发送方的IP,或者接收到数据的IP
2. public byte[] getData()
返回将要发送的数据缓冲区或已经接收到的数据缓冲区
3. public int getLength()
返回要发送的数据的长度或收到的数据的长度
package udp;
import java.net.*;
public class ServerClient {
public static void main(String[] args) {
DatagramSocket ds=null;
DatagramPacket dp=null;
try {
ds=new DatagramSocket(6666);
String str="welcome to udp programming!编程中国 你好 西安理工大学";
dp=new DatagramPacket(str.getBytes(),str.getBytes().length,
InetAddress.getByName("192.168.20.12"),7777);
ds.send(dp);
System.out.println("发送成功!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
package udp;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class ReceiveClient {
public static void main(String[] args) {
DatagramSocket ds=null;
try {
ds=new DatagramSocket(7777);
DatagramPacket dp=null;
byte[] b=new byte[1024];
dp=new DatagramPacket(b, b.length);
System.out.println("等待接收。。。");
ds.receive(dp);
byte[] data=dp.getData();
// System.out.println(b==data); //dp.getData()获取的是缓冲区的长度(byte[] b的长度)
System.out.println("接收到的数据为:"+new String(b,0,data.length)); //打印整个缓冲区的长度
System.out.println("接收到的数据为:"+new String(b,0,dp.getLength())); //打印内容的长度
} catch (Exception e) {
e.printStackTrace();
}
}
}
3、基于TCP和UDP协议的Socket编程
4、UDP通信模型
用UDP网络编程实现两个端口之间互相通信:
package chat;
import java.io.*;
import java.net.*;
public class SendRunnable implements Runnable{
private DatagramSocket ds;
private String destHost;
private int port;
public SendRunnable(DatagramSocket ds,String destHost,int port){
this.ds=ds;
this.destHost=destHost;
this.port=port;
}
@Override
public void run() {
try {
while(true){
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.println("我说:");
String str = br.readLine();
DatagramPacket dp=new DatagramPacket(str.getBytes(),str.getBytes().length,
InetAddress.getByName(destHost),port);
ds.send(dp);
}
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
package chat;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class ReceiveRunnable implements Runnable{
private DatagramSocket ds;
public ReceiveRunnable(DatagramSocket ds) {
this.ds=ds;
}
@Override
public void run() {
try {
while(true){
byte[] b=new byte[1024];
DatagramPacket dp=new DatagramPacket(b, b.length);
ds.receive(dp);
String add=dp.getAddress().getHostAddress();
int port=dp.getPort();
System.out.println(add+":"+port+"说"+new String(b,0,dp.getLength()));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
package chat;
import java.net.DatagramSocket;
import java.net.SocketException;
public class ChatA {
public static void main(String[] args) {
DatagramSocket ds=null;
try {
ds=new DatagramSocket(8888);
System.out.println("这是8888端口");
new Thread(new SendRunnable(ds,"127.0.0.1",9999)).start();
new Thread(new ReceiveRunnable(ds)).start();
} catch (SocketException e) {
e.printStackTrace();
}
}
}
package chat;
import java.net.DatagramSocket;
import java.net.SocketException;
public class ChatB {
public static void main(String[] args) {
DatagramSocket ds=null;
try {
ds=new DatagramSocket(9999);
System.out.println("这是9999端口");
new Thread(new SendRunnable(ds,"127.0.0.1",8888)).start();
new Thread(new ReceiveRunnable(ds)).start();
} catch (SocketException e) {
e.printStackTrace();
}
}
}
二、Java反射机制
反射就是把Java类中的各种成分映射成一个个的java对象。例如,一个类有:成员变量,方法,构造方法,包等等信息,利用反射技术可以对一个类进行解剖,把各个组成部分映射成一个个对象。
1、java反射常用类
反射常用的Java 类型
Class类—可获取类和类的成员信息
Field类—可访问类的属性
Method类—可调用类的方法
Constructor类—可调用类的构造方法
2、反射的基本步骤
1.导入java.lang.reflect.*
2.获得需要操作的类的Java.lang.Class对象
3.调用Class的方法获取Field、Method等对象
4.使用反射API进行操作 (设置属性﹑调用方法)
3、Class类
Class类是Java 反射机制的起源和入口
Class类的实例化对象代表一个正在运行的Java类或接口。
(1)每个类都有自己的Class 对象
(2)用于获取与类相关的各种信息
(3)提供了获取类信息的相关方法
(4)Class类继承自Object类
Class类存放类的结构信息
(1)类名
(2)父类﹑接口
(3)方法﹑构造方法﹑属性
(4)注释
4、获取Class类的三种方式
(1)对象.getClass()
Student stu=new Student();
Class clazz=stu.getClass();
(2)类.class
Class clazz= Student.class;
Class clazz=String.class;
(3)Class.forName()
clazz=Class.forName("java.lang.String");
clazz=Class.forName("java.util.Date");
package reflect;
import java.lang.reflect.Modifier;
public class ClassDemo {
public static void main(String[] args) {
Student stu=new Student();
Class> c1=stu.getClass(); // 方式一
Class c2= Student.class; // 方式二
Class> c3=null;
try {
c3=Class.forName("reflect.Student"); // 方式三
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println("方式一获取Class类对象:"+c1.getSimpleName());
System.out.println("方式二获取Class类对象:"+c2.getName());
System.out.println("方式三获取Class类对象:"+c3.getName());
int mod=c1.getModifiers(); // 获取修饰符所对应的整数
String modifier=Modifier.toString(mod);
System.out.println("Student类的修饰符:"+modifier);
}
}
package fields;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class AllField {
public static void main(String[] args) {
Class cla=Student.class;
Field[] fields=cla.getDeclaredFields();
for(Field field:fields){
System.out.println(cla.getName()+"声明的属性有:");
int mod=field.getModifiers();
String mode=Modifier.toString(mod); //获取属性修饰符
Class> type=field.getType(); //获取属性类型
String fname=field.getName(); //获取属性名
System.out.println(mode+" "+type.getSimpleName()+" "+fname);
}
}
}
5、使用反射动态创建对象
(1)使用Class的newInstance()方法,仅适用于无参构造。
Class clazz=Class.forName(“org.Student");
Object obj=clazz.newInstance();
package method;
import java.lang.reflect.Method;
public class InvokeMethod {
public static void main(String[] args) throws Exception{
Class cla=Student.class;
Student stu=cla.newInstance();
Method setmethod=cla.getMethod("setName", String.class);
setmethod.invoke(stu,"李敏");
Method getmethod=cla.getMethod("getName");
System.out.println(getmethod.invoke(stu));
}
}
(2)使用Constructor的newInstance()方法,适用于所有构造方法。
Constructor cons = clazz. ngetDeclaredConstructor(Class>... parameterTypes);
Object obj = cons.newInstance(Object.. initargs);
package constructor;
import java.lang.reflect.Constructor;
public class ConstructorDemo {
public static void main(String[] args) {
Class cls=Student.class;
try {
Constructor cons=cls.getDeclaredConstructor(String.class,int.class,double.class); // 获取三参的构造方法
Student stu=cons.newInstance("东方不败",20,99.5); // 调用三参构造,实例化对象
System.out.println(stu);
} catch (Exception e) {
e.printStackTrace();
}
}
}