zoukankan      html  css  js  c++  java
  • 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();
    	}
    

      

  • 相关阅读:
    Python-pymysql
    MySQL学习(3)
    MySQL学习(1)
    MySQL与PostgreSQL哪个更好?
    svn与git区别
    journalctl常用命令
    Spring Cloud 生产环境性能优化
    springcloud优雅停止上下线与熔断
    istio基础详解
    微服务的全链路监控
  • 原文地址:https://www.cnblogs.com/-gongxue/p/14475179.html
Copyright © 2011-2022 走看看