0303 TCP多线程上传文件,类加载,反射

已经写过单线程的上传文件的方法,那我们怎么样实现多个客户端同时链接服务器上传文件呢

代码展示 服务器端

public class UPload implements Runnable{

	private Socket socket;
	
	public UPload(Socket socket) {
		super();
		this.socket = socket;
	}

	public UPload() {
		super();
	}

	public void run() {
		//明确数据源
		//读取客户端发送过来的数据
		try {
			InputStream in = socket.getInputStream();
			//明确目的地文件的位置
			File file=new File("F:\\io1127\\server");
			//如果文件夹不存在 就创建
			if(!file.exists()){
				file.mkdirs();
			}
			//明确文件名
			String filename="oracle"+System.currentTimeMillis()+new Random().nextInt(9999)+".jpg";
			//明确目的地
			FileOutputStream fos=new FileOutputStream(file+File.separator+filename);
			//开始复制
			byte[] bytes=new byte[1024];
			int len=0;
			while((len=in.read(bytes))!=-1){
				fos.write(bytes,0,len);
			}
			//回复客户端
			//获取字节输出流
			OutputStream out=socket.getOutputStream();
			//回复内容
			out.write("收到".getBytes());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

}

  代码展示服务器

public class TCPSever {

	public static void main(String[] args) throws IOException {
		//创建服务器对象
		ServerSocket server=new ServerSocket(8888);
		while(true){
			//创建连接
			Socket socket=server.accept();
			//创建线程并开启
			new Thread(new UPload(socket)).start();
		}
	}
}

  代码展示客户端(客户端代码没有改变)

public class TCPlient {

	public static void main(String[] args) throws UnknownHostException, IOException {
		//创建客户端对象明确服务器端的ip和端口号
		Socket socket=new Socket("192.168.1.171",8888);
		//明确读取数据的数据源
		FileInputStream fis=new FileInputStream("F:\\io1127\\3.jpg");
		//明确目的地 获得字节输出流
		OutputStream out=socket.getOutputStream();
		int len=0;
		byte[] bytes=new byte[1024];
		while((len=fis.read(bytes))!=-1){
			out.write(bytes,0,len);
		}
		//告知服务器端结束
		socket.shutdownOutput();
		//接收服务器端的回复
		InputStream in=socket.getInputStream();
		len=in.read(bytes);
		System.out.println("服务器端回复:"+new String(bytes,0,len));
		//释放资源
		socket.close();
		
	}
}

 1、类加载

当程序使用某个类的时候,如果该类未被加载到内存中,则系统就会通过加载,链接,初始化三个步骤进行类的初始化

(1)加载,就是将class文件读入内存,并为之创建一个Class对象,在任何一个类被使用的时候会创建一个Class对象,该文件叫字节码文件

图解:

 

 

 

(2)链接,

  验证,是否有真做正确的内部结构,与其他类协调一致

  准备,负责为类的静态成员分配内存,并设置默认初始化值

  解析,将二进制中的符号引用替换为直接引用

(3)初始化,

类的初始化机制(什么时候类被加载到内存)

1、创建类对象

2、类的静态变量或者为静态变量赋值

3、类的静态方法

4、反射

5、初始化某个子类

6、直接使用java.exe运行某个主类

是谁让让类加载到内存中,并为之生成class对象呢,就是类的加载器

类的加载器将.class文件加载到内存中,并为之生成class文件

(1)根类加载器,跟类加载器用于加载jdk中写好的一些类,例如String System类

(2)扩展类加载器,就是加载那些我们引入的那些jar包 jdbc驱动包啊,commensIO之类的jar包

(3)系统类加载器,一般加载我们自定义的类,加载java命令的class文件

那么类已经加载到内存了,那我们如何获得这个Class类的字节码文件,并获得里边的多有内容呢

获取字节码文件对象,获取这个类所有的成员变量也好成员方法也好等等这些东西,这个过程就叫做反射。

获取Class类字节码文件的方式 三种

先创建一个Person类

public class Person {

	private int age;
	String name;
	public Person() {
		System.out.println("public person()");
	}
	private Person(String name) {
		System.out.println("private person(String name)");
	}
	public void eat(){
		System.out.println("public void eat()");
	}
	public void sleep(String name){
		System.out.println("public void sleep(String name)");
	}
}

  创建测试类 获取字节码文件

	public static void main(String[] args) throws ClassNotFoundException {
		//通过object中getclass方法 获取字节码对象
		Person p=new Person();
		Class c=p.getClass();
		System.out.println(c);
		//通过类名调用class属性获取
		Class c2=Person.class;
		System.out.println(c2);
		//forname 方法
		Class c3=Class.forName("com.oracle.demo02.Person");
		System.out.println(c3);
	}

  ‘

能够获取到字节码文件 怎样获取里边的构造方法并且使用呢

在反射机制中,把类中的成员(构造方法、成员方法、成员变量)都封装成了对应的类进行表示

构造方法使用类Constructor表示

这个构造方法类中提供了返回构造方法的方法,我们先看返回一个构造方法的方法

public Constructor<T> getConstructor(Class<?>... parameterTypes)获取public修饰指定参数类型的构造方法

public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)获取指定参数类型的构造方法(公有和私有都包括在内)

构造方法类Constructor中有一个public T newInstance(Object... initargs) 方法 创建一个构造方法类对象

代码展示

	public static void main(String[] args) throws 
					ClassNotFoundException, NoSuchMethodException, 
					SecurityException, InstantiationException, 
					IllegalAccessException, IllegalArgumentException, 
					InvocationTargetException {
		//获取字节码文件对象
		Class c=Class.forName("com.oracle.demo02.Person");
		//获取字节码文件对象构造方法 公共
		Constructor con=c.getConstructor();
		System.out.println(con);
		//创建对象
		Person p=(Person)con.newInstance();
		p.eat();
	}

  

posted @ 2021-03-03 16:19  公雪  阅读(123)  评论(0编辑  收藏  举报