zoukankan      html  css  js  c++  java
  • udp和tcp

    网络通信协议

    tcp/ip协议:包括TCP协议和IP协议,UDP协议和其它一些协议的协议组

    层次结构:应用层---传输层---网络层---链路层

    ip地址:唯一标识一台计算机  

    ipv4版本:4个字节的二进制数表示(一共4个字节,一个字节有8位,用0和1表示),转换成十进制后就是常见的形式,127.0.0.1

    端口:通过ip地址找到 计算机,然后通过端口号来找到指定的应用程序

    inetaddress类:封装一个ip地址,包含主机名

    构造方法

    getbyname():静态方法,需要传一个字符串表示的ip地址,返回一个inetaddress对象

    getlocalhost():静态方法,空参,返回本地主机的inetaddress对象

    方法

    gethostname():空参,返回表示此ip地址的主机名的字符串

    gethostaddress():空参,返回表示ip地址的字符串

    InetAddress inet = InetAddress.getLocalHost();
            //System.out.println(inet);
    //        String[] str = inet.toString().split("/");
    //        for(String s:str){
    //            System.out.println(s);
    //        }
            //System.out.println(inet.getHostName());
            //System.out.println(inet.getHostAddress());
            InetAddress inet1 = InetAddress.getByName("123-pc");
            System.out.println(inet1);

    udp协议:无连接通信协议,数据传输时,数据的发送端和接收端不建立逻辑连接

    占用资源小,通信效率高,视频、音频和普通数据的传输,丢包不会对结果产生太多影响

    传输重要数据不适用udp

    数据大小被限制在64k以内

    tcp协议:面向连接的通信协议,传输数据前先在发送端和接收端建立逻辑连接,然后再传输数据,提供了两台计算机之间可靠无差错的数据传输

    面向连接的特效,保证了数据传输的安全性(完整性),下载文件时采用tcp协议

    udp的使用

    datagrampocket类:用来打包用户的数据,相当于集装箱

    getaddress():返回一个inetaddress对象

    getport():返回端口号

    getlength():用来获取数据的大小

    datagramsocket类:用来传输集装箱,相当于码头

    send():发送数据

    receive():接收数据

    发送端:使用datagrampocket类四个参数的构造方法;使用datagramsocket类的空参构造(不需要指定端口号,系统自动分配一个没被占用的端口号)

    接收端:使用datagrampocket类两个参数的构造方法;使用datagramsocket类的有参构造(指定端口号,可以监听指定的端口号)

    byte[] bytes = "你好".getBytes();
            InetAddress inet = InetAddress.getLocalHost();
            DatagramPacket dp = new DatagramPacket(bytes, bytes.length, inet, 8000);
            DatagramSocket ds = new DatagramSocket();
            ds.send(dp);
            ds.close();
    DatagramSocket ds = new DatagramSocket(8000);
            byte[] bytes = new byte[1024];
            DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
            ds.receive(dp);
            int len = dp.getLength();
            String ip = dp.getAddress().getHostAddress();
            int port = dp.getPort();
            System.out.println(ip+"..."+port+"..."+new String(bytes,0,len));
            ds.close();

     tcp的使用

    客户端:scocket

    构造方法:有参构造,传入一个表示服务器端ip地址的字符串和端口号

    方法:getinputstream()获得输入流;getoutputstream()获得输出流

    不需要自己去创建流,用方法调用

    服务器端:serversocket

    构造方法:有参构造,传入端口号

    方法:accept()获得一个socket对象,调用其方法

    Socket socket = new Socket("127.0.0.1", 8888);
            OutputStream out = socket.getOutputStream();
            FileInputStream fis = new FileInputStream("d:\12\123.jpg");
            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));
            fis.close();
            socket.close();
    ServerSocket server = new ServerSocket(8888);
            Socket socket = server.accept();
            InputStream in = socket.getInputStream();
            File upload = new File("d:\12\upload");
            if(!upload.exists()){
                upload.mkdirs();
            }
            String filename = "oracle"+System.currentTimeMillis()+new Random().nextInt(9999)+".png";
            FileOutputStream fos = new FileOutputStream(upload+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());
            fos.close();
            socket.close();
            server.close();

    服务器端多线程:

    public class Upload implements Runnable {
        private Socket socket;
        private FileOutputStream fos;
        public Upload(Socket socket){
            this.socket = socket;
        }
        @Override
        public void run() {
            // TODO Auto-generated method stub
            try{
            InputStream in = socket.getInputStream();
            File upload = new File("d:\12\upload");
            if(!upload.exists()){
                upload.mkdirs();
            }
            String filename = "oracle"+System.currentTimeMillis()+new Random().nextInt(9999)+".png";
            fos = new FileOutputStream(upload+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(Exception e){
                e.printStackTrace();
            }finally{
                try {
                    fos.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                try {
                    socket.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    
    }
    ServerSocket server = new ServerSocket(8888);
            while (true) {
                Socket socket = server.accept();
                Upload upload = new Upload(socket);
                Thread thread = new Thread(upload);
                thread.start();
            }

    类加载

    类未被加载到内存中,系统通过加载,连接,初始化三步对此类进行初始化

    加载:把class文件加载到内存中,并生成一个class文件

    连接:1、验证,验证类的内部结构,并与其它类协调;2、准备,为静态成员分配内存,并赋值;3、解析,将二进制的符号引用变成直接引用

    初始化:学过的

    类初始化时机:1、创建类的对象;2、给静态成员变量赋值;3、使用静态方法;4、反射;5、初始化某个类的对象;6、直接java.exe来运行某个类

    类的加载器:根类加载器   扩展类加载器   系统类加载器

    反射

    在java中,动态获取信息及动态调用对象方法的功能叫做反射机制

    class类

    构造方法:没有,只能通过方法获得对象

    1、某类的对象调用getclass()方法

    2、类名直接调用class静态成员变量

    3、class.forname(),传入一个字符串,可以和properties文件一起使用

    Person p = new Person();
           // Class c = p.getClass();
          //  System.out.println(c);
          //  Class c1 = Person.class;
      //      System.out.println(c1);
    //        System.out.println(c==c1);
    //        System.out.println(c.equals(c1));
    //        Class c2 = Class.forName("com.oracle.demo02.Person");
    //        System.out.println(c2);

    方法:

    constructor:表示构造方法

    field:表示成员变量

    method:表示成员方法

    declared:可以获得私有和公有的所有方法

    setAccessible():允许对私有化的成员进行修改,暴力反射中的

    constructor中的newinstance()方法,返回的是一个obj类型的对象,如果需要使用本类的方法,需要强转

    //反射获取空参构造
            Class c = Class.forName("com.oracle.demo02.Person");
            //获取所有的公共构造方法
    //        Constructor[] con = c.getConstructors();
    //        for(Constructor c1:con){
    //            System.out.println(c1);
    //        }
            Constructor con = c.getConstructor();
            //Object obj = con.newInstance();
            Person p = (Person)con.newInstance();
            p.work("zhangsan");
            //System.out.println(obj);
    //获取有参构造
            Class c = Class.forName("com.oracle.demo02.Person");
            Constructor con = c.getConstructor(String.class,int.class);
            System.out.println(con);
            Object obj = con.newInstance("zhangsan",18);
            System.out.println(obj);
    //快速获取空参构造方法并创建对象
    //        Class c = Class.forName("com.oracle.demo02.Person");
    //        Object obj = c.newInstance();
    //        System.out.println(obj);
            //获取私有的构造方法
            //暴力反射,破坏了程序的封装性和安全性
            Class c = Class.forName("com.oracle.demo02.Person");
    //        Constructor[] con = c.getDeclaredConstructors();
    //        for(Constructor cc:con){
    //            System.out.println(cc);
    //        }
            Constructor con = c.getDeclaredConstructor(int.class,String.class);
            //System.out.println(con);
            con.setAccessible(true);
            Object obj = con.newInstance(18,"zhangsan");
            System.out.println(obj);
        }
    //通过反射获取成员变量并改值
            Class c = Class.forName("com.oracle.demo02.Person");
            Object obj = c.newInstance();
    //        Field[] fields = c.getFields();
    //        for(Field f:fields){
    //            System.out.println(f);
    //        }
            Field field = c.getField("name");
            Field field1 = c.getDeclaredField("age");
            //System.out.println(field);
            field.set(obj, "zhangsan");
            field1.setAccessible(true);
            field1.set(obj, 25);
            System.out.println(obj);
        }
    //获取所有公共的方法,包括继承来的
    //        Method[] m = c.getMethods();
    //        for(Method mm:m){
    //            System.out.println(mm);
    //        }
            Method method = c.getMethod("eat");
            System.out.println(method);
            method.invoke(c.newInstance());
    //获取有参方法并运行
            Class c = Class.forName("com.oracle.demo02.Person");
            Method method = c.getMethod("work", String.class);
            method.invoke(c.newInstance(), "zhangsan");

    泛型擦除

    有泛型的类,在程序进行编译后生成的class文件中,没有泛型约束,这叫做泛型擦除

    //有一个ArrayList<String> list
            //然后往里面添加int类型数据
            //泛型擦除,字节码文件中没有泛型
            ArrayList<String> arr = new ArrayList<String>();
            arr.add("abc");
            Class c = arr.getClass();
            Method addd = c.getMethod("add", Object.class);
            addd.invoke(arr, 1);
            for(Object o:arr){
                System.out.println(o);
            }

    反射配置文件

    //类不清楚,方法也不清楚
            //通过配置文件去实现,运行类名和方法名已键值对的形式
            //保存到properties中,具体运行哪个类里面的方法通过改配置文件去设置
            //1.准备配置文件,写好键值对
            //2.IO读取配置文件reader
            //3.文件中的键值对存储到集合中,集合中保存的键值对就是类名和方法名
            //4.反射获取指定类的class文件对象
            //5.class文件对象获取指定方法
            //6.运行方法
            //Person p = new Person();
            //p.eat();
            FileReader fr = new FileReader("config.properties");
            Properties pro = new Properties();
            pro.load(fr);
            fr.close();
            String className = pro.getProperty("className");
            String methodName = pro.getProperty("method");
            Class c = Class.forName(className);
            Object obj = c.newInstance();
            Method method = c.getMethod(methodName);
            method.invoke(obj);
  • 相关阅读:
    第72届奥斯卡最佳动画奖《老人与海》
    关不掉的手机应用程序
    李嘉诚:知识并不一定使你的财富增加
    Linux之父Linus Torvalds谈软件开发管理经验
    Google 正式发布Dart编程语言
    代码本身其实并不重要,重要的是用户
    22个基于HTML5开发的网站
    看看耶鲁大学心态 ,送给正在奋斗的人 !
    用 git 维护 vim 代码
    谈程序语言的设计及程序员心态
  • 原文地址:https://www.cnblogs.com/yelena-niu/p/9248326.html
Copyright © 2011-2022 走看看