网络(Java.net)

IPv4地址分类

端口号 

网络通信协议 

在网络编程中,数据的组织形式就是协议

TCP UDP 协议 

 

InetAddress类 

 public static void main(String[] args) throws UnknownHostException {
        InetAddress localHost = InetAddress.getLocalHost();//获取本机的InetAddress对象(主机名和IP地址)
        System.out.println(localHost);
        InetAddress byName = InetAddress.getByName("DESKTOP-Ding");//指定主机名,获取InetAddress对象(主机名和IP地址)
        System.out.println(byName);
        InetAddress byName1 = InetAddress.getByName("www.baidu.com");//根据域名,获取InetAddress对象(域名和IP地址)
        System.out.println(byName1);
        String hostAddress = localHost.getHostAddress();//反向获取IP地址
        System.out.println(hostAddress);
        String hostName = byName1.getHostName();//反向获取域名
        System.out.println(hostName);
    }

//输出

DESKTOP-Ding/169.254.159.192
DESKTOP-Ding/169.254.159.192
www.baidu.com/110.242.68.3
169.254.159.192
www.baidu.com

 Socket套接字(TCP)

socket位于数据通道两端,两端都有socket.getInputSteam(输入流)和socket.getOutputStream(输出流),一端输出另一端就输入。服务器处于监听状态,时刻等待客户端的链接

两种编程方式:

        1.TCP编程

        2.UDP编程

 代码实现(字节流)

 服务器一定要先开启服务,等待客户端的链接

本地主机Host
public class Host {//本地主机
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket(InetAddress.getLocalHost(), 9999);//设置服务器的IP地址,主机名和端口号
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write("hi server".getBytes());//向服务器发送内容
        socket.shutdownOutput();//输出结束标记  结束服务器等待
        InputStream inputStream = socket.getInputStream();
        byte[] bytes = new byte[1024];
        int read = 0;
        while((read = inputStream.read(bytes))!= -1){
            System.out.println(new String(bytes,0,read));//接受服务器的信息
        }
        //关闭资源,避免浪费
        outputStream.close();
        inputStream.close();
        socket.close();

    }
}
 服务器Server
public class Server {//服务器
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(9999);//设置服务器对应端口号
        System.out.println("等待链接:");
        Socket accept = serverSocket.accept();//通道监听

        InputStream inputStream = accept.getInputStream();
        byte[] bytes = new byte[1024];
        int read = 0;
        while((read = inputStream.read(bytes))!=-1){//接受主机发送的信息
            System.out.println(new String(bytes,0,read));
        }
        OutputStream outputStream = accept.getOutputStream();
        outputStream.write("已接受".getBytes());//向主机发送信息
        accept.shutdownOutput();//输出结束标记
        //关闭资源,避免浪费
        outputStream.close();
        serverSocket.close();
        accept.close();
    }
}

代码实现(字符流)

本地主机Host
public class Host {//本地主机
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket(InetAddress.getLocalHost(), 9999);//设置服务器的IP地址,主机名和端口号

        //使用字符输出流输出信息
        OutputStream outputStream = socket.getOutputStream();
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
        bufferedWriter.write("hello");
        bufferedWriter.newLine();//插入换行符,表示写入内容结束。对方需要readLine()接受
        bufferedWriter.flush();//使用字符流手动刷新才能进入通信通道

        //使用字符输入流接收信息
        InputStream inputStream = socket.getInputStream();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        String s = bufferedReader.readLine();//通过readLine()接受信息
        System.out.println(s);
        //关闭资源,避免浪费
        bufferedReader.close();
        bufferedWriter.close();
        socket.close();//通道关闭

    }
}
服务器Server
public class Server {//服务器
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(9999);//设置服务器对应端口号
        System.out.println("等待链接:");
        Socket socket = serverSocket.accept();//通道监听

        //使用字符输入流接受客户端信息
        InputStream inputStream = socket.getInputStream();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        String s = bufferedReader.readLine();//readLine()接受
        System.out.println(s);

        //使用字符输出流输出信息
        OutputStream outputStream = socket.getOutputStream();
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
        bufferedWriter.write("hi");
        bufferedWriter.newLine();//输出信息结束标记
        bufferedWriter.flush();//字符输出流手动刷新才可进入通信通道
        //关闭资源,避免浪费
        bufferedWriter.close();
        bufferedReader.close();
        serverSocket.close();//服务器对象关闭
        socket.close();//通信通道关闭
    }
}

netstat(DOS命令)

UDP网络通信编程 (了解)

不指定发送端口,但是两端得指定接收端口

 

 代码实现

接收端
public class Receive {//接收端A
    public static void main(String[] args) throws IOException {
        DatagramSocket socket = new DatagramSocket(9999);//创建接收对象的接口
        byte[] buf = new byte[1024];
        DatagramPacket packet = new DatagramPacket(buf, buf.length);//创建通道
        //调用接收方法,将通过网络传输的DatagramPacket对象,填充到packet
        socket.receive(packet);
        //可以把packet进行拆包,取出数据并显示
        int length = packet.getLength();//实际收到的数据长度
        byte[] data = packet.getData();//实际收到的数据
        String s = new String(data, 0, length);
        System.out.println(s);
        socket.send(packet);//发送
        //回复信息给B端
         data = "Hi".getBytes();
         packet = new DatagramPacket(data, data.length, InetAddress.getLocalHost(),9998);

        socket.close();//关闭资源
    }
}
发送端
public class Send {//发送端B
    public static void main(String[] args) throws IOException {
        DatagramSocket socket = new DatagramSocket(9998);//创建DatagramSocket对象,在9998端口接收数据
        //将需要发送的数据封装到DatagramPacket对象
        byte[] data = "hello".getBytes();
        DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getLocalHost(),9999);
        socket.send(packet);//发送

        //接收A端消息
        byte[] buf = new byte[1024];
         packet = new DatagramPacket(buf, buf.length);//创建通道
        //调用接收方法,将通过网络传输的DatagramPacket对象,填充到packet
        socket.receive(packet);
        //可以把packet进行拆包,取出数据并显示
        int length = packet.getLength();//实际收到的数据长度
        data = packet.getData();//实际收到的数据
        String s = new String(data, 0, length);
        System.out.println(s);
        socket.send(packet);//发送

        socket.close();//关闭资源

    }
}

 

多用户通信系统演示

项目开发流程

 

二 

反射

动态代理:无侵入式的给代码增加额外的功能。对象如果嫌身上的干的事太多,可以通过代理来转移部分职责。 对象有什么方法想被代理。代理就一定要有对应的方法

 获取类对象

如何获取类对象 

Person类

public class Person {
     String name;
     int age;
    public void eat(){
        System.out.println(name + age+"吃饭");
    }
    //无参构造器
    public Person() {

    }
    //有参构造器
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

TestPerson类

推荐使用第三种方法,依赖性相对较弱

public class TestPerson {
    public static void main(String[] args) throws Exception {
        getClazz();
    }
    public static void getClazz() throws ClassNotFoundException {
        //使用对象获取类对象
        Person zhangsan = new Person();
        Class<?> class1 =zhangsan.getClass();
        System.out.println(class1.toString());
        //使用类名.class属性 【推荐使用】
        Class<?> class2 = Person.class;
        System.out.println(class2.toString());
        //使用Class的静态方法
        Class<?> class3 = Class.forName("reflect.Person");
        System.out.println(class3.toString());
    }

}

与反射相关的常用方法

 

使用反射获取类的构造方法并创建实例
public static void refelctOp1() throws ClassNotFoundException {
        Class<?> class1 = Class.forName("reflect.Person");
        Constructor<?>[] constructors = class1.getConstructors();
        for (Constructor<?> o :constructors) {//遍历
            System.out.println(o.toString());
        }
 }
在主方法运行 输出结果。
public reflect.Person(java.lang.String,int)
public reflect.Person()
public static void refelctOp1() throws Exception {
        Class<?> class1 = Class.forName("reflect.Person");
        //获取类中无参构造
        Constructor<?> con = class1.getConstructor();
        Person person1 = (Person) con.newInstance();//创建一个实例
        System.out.println("person1:"+person1.toString());
        //简便方法 类对象.newInstance()
        Person person2 =(Person) class1.newInstance();//使用了强制转换 Object person2 =class1.newInstance()
        System.out.println("person2:"+person2.toString());
        //获取类中带参构造
        Constructor<?> con2 = class1.getConstructor(String.class, int.class);
        Person jack =(Person) con2.newInstance("jack", 20);
        System.out.println(jack);
    }
主方法运行 输出结果。
person1:Person{name='null', age=0}
person2:Person{name='null', age=0}
Person{name='jack', age=20}
使用反射获取类中的方法并调用

调用使用invoke()方法,第一个参数调用方法的对象,第二个是方法的参数 

public static void refelctOp2() throws Exception{
        Class<?> class1 = Class.forName("reflect.Person");

        Method[] methods = class1.getMethods();// getMethods()只获取类中公开的方法,包括从父类继承的方法
        Method[] declaredMethods = class1.getDeclaredMethods();//getDeclaredMethods获取类中所有方法,不包含继承的
        for (Method method :declaredMethods) {
            System.out.println(method.toString());
        }  
      
        //获取无参的方法并调用
        Method methods = class1.getMethod("eat");
        Person P1 =(Person) class1.newInstance();//创建类的实例对象
        methods.invoke(P1);//调用方法  相当于  P1.eat()

        //获取toString方法并调用
        Method toString = class1.getMethod("toString");
        Object invoke = toString.invoke(P1);//有返回值,需要接受
        System.out.println(invoke);

        //获取带参方法并调用
        Method eat = class1.getMethod("eat", String.class);
        eat.invoke(P1, "鸡腿");
        //获取私有方法并调用
        Method privateMethod = class1.getDeclaredMethod("privateMethod");
        privateMethod.setAccessible(true);//调用时有私有访问限制,设置私有访问无效
        privateMethod.invoke(P1);

        //获取静态方法并调用
        Method staticMethod = class1.getMethod("staticMethod");
        staticMethod.invoke(null);
}
输出结果

null0吃饭
Person{name='null', age=0}
null吃鸡腿
这是私有方法
这是静态方法

方法

public class Person {
     String name;
     int age;
    public void eat(){
        System.out.println(name + age+"吃饭");
    }
    public void eat(String food){
        System.out.println(name + "吃"+food);
    }
    private void privateMethod(){
        System.out.println("这是私有方法");
    }
    public static  void staticMethod(){
        System.out.println("这是静态方法");
    }
    public Person() {

    }
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
使用反射获取类中所有方法的通用方法
ublic class TestPerson {
    public static void main(String[] args) throws Exception {
        Person person = new Person();
        //person.eat("米饭");
        invokeAny(person,"eat",new Class[]{String.class},"米饭" );
    }

    public static Object invokeAny(Object obj,String methodName,Class<?>[] types,Object...args) throws Exception{
        Class<?> class1 = obj.getClass();//获取类对象
        Method method = class1.getMethod(methodName, types);//通过反射调用方法,方法名字和参数
        return method.invoke(obj,args);//调用
    }
}
该方法
public void eat(String food){
        System.out.println(name + "吃"+food);
}
输出结果
null吃米饭
使用反射获取类中的属性
public static void md() throws Exception {
        Class<?> class1 = Class.forName("reflect.Person");
        //获取属性公开的,包括父类继承的
        Field[] field = class1.getFields();
        //获取所有属性,包括私有,保护和默认,不包含继承
        Field[] declaredFields = class1.getDeclaredFields();
        for (Field field1 :declaredFields) {
            System.out.println(field1.toString());
        }
        //获取单个属性
        Field name = class1.getDeclaredField("name");//获取name属性
        //name.setAccessible(true);//若属性为私有,则设置访问权限无效即可
        Person  P1 = (Person) class1.newInstance();//Person P1 = new Person()
        name.set(P1,"张三");//P1.name = "张三"
        System.out.println("name"+name.get(P1));//获取输出
    }
输出
java.lang.String reflect.Person.name
int reflect.Person.age
name张三

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值