网络编程
三要素:1.IP地址 2.端口 3.协议
InetAddress互联网协议 (IP) 地址
封装了IP地址的类
用法:
public static void main(String[] args){//获取IP地址try {InetAddress ia=InetAddress.getByName("www.baidu.com");System.out.println(ia);//www.baidu.com/110.242.68.3//返回本地域名System.out.println(ia.getHostName());//www.baidu.com//返回IP地址System.out.println(ia.getHostAddress());//110.242.68.3System.out.println(ia.getCanonicalHostName());//110.242.68.4//获取本机地址InetAddress localHost = ia.getLocalHost();System.out.println(localHost);} catch (UnknownHostException e) {throw new RuntimeException(e);}}
URL路径
用法:
public static void main(String[] args) {//URL路径try {URL url=new URL("https://www.baidu.com:80/index.html#muzhou");System.out.println("协议:"+url.getProtocol());//协议:httpsSystem.out.println("域名:"+url.getHost());//域名:www.baidu.comSystem.out.println("端口:"+url.getPort());//端口:80System.out.println("资源:"+url.getFile());//资源:/index.htmlSystem.out.println("锚点:"+url.getRef());//锚点:muzhouSystem.out.println("相对路径:"+url.getPath());//相对路径:/index.htmlSystem.out.println("参数:"+url.getQuery());//null} catch (MalformedURLException e) {throw new RuntimeException(e);}}
常用端口:
3306 mysql
1521 oracle
80 web
8080 tomcat
4000 QQ
2425 飞秋feiQ
协议:
UDP协议:
用户数据 面向无连接 数据不安全 速度快 不区分客户端和服务端
(例子:相当于发短信 不论对方是否在线 是否能接收到)
Socket通信(套接字):
网络上具有唯一标识的IP地址和端口号组合在一起 才能构成唯一能识别的标识符套接字
通信的两端都有Socket
网络通信其实就是Socket间的通信
数据在Socket中通过IO流传输
案例:UDP传输多线程
//(服务端)接收
public class Reciver extends Thread {public void run(){//建立码头DatagramSocket s=null;try {//指定端口号9999s=new DatagramSocket(9999);//货轮byte[] b=new byte[1024];//集装箱接受数据DatagramPacket p=new DatagramPacket(b,1024);while(true){//将数据装载到集装箱中s.receive(p);//获取数据来源的地址InetAddress ip=p.getAddress();String msg=new String(b);System.out.println("从"+ip+"发送过来"+msg);}} catch (Exception e) {throw new RuntimeException(e);}finally{s.close();}}}
//(客户端)发送
public class Sender extends Thread {public void run(){//创建码头DatagramSocket s=null;while(true){try {s=new DatagramSocket();//准备备货物Scanner sc=new Scanner(System.in);System.out.println("请客户端输入:");String msg=sc.next();//创建货轮byte[] b=msg.getBytes();//获取客户地址InetAddress ip=InetAddress.getByName("127.0.0.1");//将货物装入集装箱DatagramPacket p=new DatagramPacket(b,0,b.length,ip,9999);//发送s.send(p);} catch (Exception e) {throw new RuntimeException(e);}finally{s.close();}}}
}
//测试public static void main(String[] args) {Reciver r=new Reciver();r.start();Sender s=new Sender();s.start();}
(重点)TCP协议:
传输控制 面向连接(三次握手) 数据安全 速度略慢 分为客户端和服务段
(例子1:打电话 呼叫 接听 数据传输)(例子2:网站访问:客户端发送请求 连接服务器 数据传输)
案例:TCP传输多线程
public class Sender extends Thread{public void run(){ServerSocket ss=null;BufferedReader br=null;try {//创建服务端的套接字ss=new ServerSocket(8888);//阻塞Socket socket=ss.accept();//读取客户端的流InputStream in=socket.getInputStream();br=new BufferedReader(new InputStreamReader(in));while(true){String msg=br.readLine();System.out.println("客户端发来:"+msg);}} catch (Exception e) {throw new RuntimeException(e);}finally{if(br!=null){try {br.close();} catch (IOException e) {throw new RuntimeException(e);}}}}
}
public class Client extends Thread {OutputStream out=null;BufferedWriter bw=null;public void run(){try {//定位Socket s=new Socket("127.0.0.1",8888);//发送out=s.getOutputStream();bw=new BufferedWriter(new OutputStreamWriter(out));Scanner sc=new Scanner(System.in);while(true){System.out.println("请客户端输入:");String str=sc.next();bw.write(str);bw.newLine();bw.flush();}} catch (IOException e) {throw new RuntimeException(e);}finally{if(bw!=null){try {bw.close();} catch (IOException e) {throw new RuntimeException(e);}}}}
}
public class Test_Client {public static void main(String[] args) {Client c=new Client();c.start();}
}
public class Test_Sender {public static void main(String[] args) {Sender s=new Sender();s.start();}
}
反射 (解剖 类)
对于任意一个类 都能知道这个类中的所有属性和方法
对于任意一个对象 都能够调用它任意的方法和属性
动态获取的信息以及动态调用对象的方法 称为java的反射机制
类的加载:
类的加载概述:当程序要使用某个类时,如果该类没有加载到内存中 系统将通过加载,连接,初始化三步实现对这个类进行初始化
加载:将class文件读入内存 并为之创建一个class对象 任何类被使用时系统都会创建一个class对象
连接:
验证:是否有正确的内部结构 并和其他类协调一致
准备:负责为类的静态成员分配内存 并赋值 默认值
解析:将类的二进制数据中的符号引用替换为直接引用
初始化
平时使用的
类加载器(classLoader):负责将.class文件加载到内存中 并为之生成对应的class对象
类加载器分为:根类加载器 扩展类加载器 系统类加载器
字节码加载时机:
创建类的实例(new)
访问类的静态变量或者为静态变量赋值
调用类的静态方法 使用反射方式强制创建某个类或接口对应的class对象
初始化某个类的子类 直接使用java.exe命令运行某个主类
获取字节码文件
三种方式获取字节码文件
//三种方式获取字节码文件//第一种Class c1=Class.forName("com.muzhou.lesson.Person");//第二种Class c2=Person.class;//第三种Person p=new Person();Class c3=p.getClass();//验证三种方法取出的字节码文件是否相同System.out.println(c1==c2);//trueSystem.out.println(c2==c3);//true
反射创建无参构造和有参构造
第一种
//获取反射无参构造和有参构造创建public static void main(String[] args) throws Exception {//Class类的.newInstance()是使用该类的无参构造方法创建对象//如果一个类没有无参构造 就不能这么创建 会报错 InstantiationExceptionClass clazz=Class.forName("com.muzhou.lesson.clazz.Person");//通过无参构造创建对象/* Person p =(Person) clazz.newInstance();System.out.println(p);//Person{name='null', age=0}*///获取有参构造 没有无参构造创建对象//clazz.getConstructor(String.class,int.class);//String.class,int.class要与Person类中的属性对应Constructor c = clazz.getConstructor(String.class, int.class);//通过有参构造创建对象Person p=(Person)c.newInstance("张三",23);System.out.println(p);//Person{name='张三', age=23}
第二种
//反射其实就是在分解class对象Class<Person> clazz=Person.class;//这个过期了 Person p1 =clazz.newInstance();//现在使用.getDeclaredConstructor().newInstance();创建一个无参构造器对象 再用对象创建实例Person p1 = clazz.getDeclaredConstructor().newInstance();p1.setName("张三");p1.setAge(23);System.out.println(p1);Constructor<Person> c = clazz.getDeclaredConstructor(String.class, int.class);Person p2 =c.newInstance("李四", 24);p2.eat();p2.eat(10);System.out.println(p2);
反射获取成员变量(如果是私有的就用暴力反射)
Class clazz=Class.forName("com.muzhou.lesson.clazz.Person");Constructor c = clazz.getConstructor(String.class, int.class);Person p =(Person)c.newInstance("张三", 23);//clazz.getFields("name");可以获取到类中指定的字段(必须是可见的public)/* Field f = clazz.getFields("name");f.set(p,"李四");*///暴力反射Field f = clazz.getDeclaredField("name");//在这一步去除私有权限 变成publicf.setAccessible(true);f.set(p,"李四");System.out.println(p);
反射获取方法
//反射获取方法Class clazz=Class.forName("com.muzhou.lesson.clazz.Person");Constructor c = clazz.getConstructor(String.class, int.class);Person p =(Person) c.newInstance("张三", 23);//通过clazz获取Method 返回的是Method 获取eat方法Method m1 = clazz.getMethod("eat");//eat不用加()m1.invoke(p);//获取带参数的方法Method m2 = clazz.getMethod("eat", int.class);m2.invoke(p,10);
反射获取所有属性
Class<Person> clazz=Person.class;//获取所有成员变量Field[] fields =clazz.getDeclaredFields();System.out.println(fields.length);//2for (Field f : fields) {System.out.println(f.getName()+"----"+f.getAnnotatedType());}//获取所有构造Constructor<?>[] c = clazz.getDeclaredConstructors();for (Constructor cs : c) {System.out.println(cs);}//获取所有方法Method[] m = clazz.getDeclaredMethods();for (Method method : m) {System.out.println( method.getName()+"返回类型"+method.getGenericReturnType()+"方法中形式参数"+method.getGenericParameterTypes());}