栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

22-05-05 西安 javaSE(18) 网络编程与jdk8新特性

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

22-05-05 西安 javaSE(18) 网络编程与jdk8新特性

网络编程

在网络间完成数据的传输,io流在本地完成数据的传输

网络编程2要素

  1. 如何准确地定位网络上一台或多台主机【ip】
  2. 找到主机后如何可靠高效地进行数据传输。【协议】

通信规则

  1. OSI参考模型:模型过于理想化
  2. TCP/IP参考模型(或TCP/IP协议):事实上的国际标准
     

端口号

端口号标识正在计算机上运行的进程, 被规定为一个 16 位的整数 0~65535。

其中,0~1023被预先定义的服务通信占用(如MySql占用端口3306,http占用端口80等)。除非我们需要访问这些特定服务,否则,就应该使用 1024~65535 这些端口中的某一个进行通信,以免发生端口冲突。 


InetAddress  java.net 

唯一标识 Internet 上的计算机,InetAddress类主要表示IP地址,有两个子类:Inet4Address、Inet6Address。

主机有两种方式表示地址
IP和域名。
域名解析:先找本机hosts,是否有输入的域名地址,没有的话,再通过DNS服务器,找主机。
在hosts文件  C:WindowsSystem32driversetc
ip地址:127.0.0.1  本地域名:localhost 

    @Test
    public void test01() throws Exception {
        InetAddress byName = InetAddress.getByName("www.baidu.com");
        //获取InetAddress实例域名
        System.out.println(byName.getHostName());
        //获取InetAddress实例ip地址
        System.out.println(byName.getHostAddress());
        System.out.println("------------------");
        InetAddress localHost = InetAddress.getLocalHost();
        //获取本地主机域名
        System.out.println(localHost.getHostName());
        //获取本地主机ip地址
        System.out.println(localHost.getHostAddress());
    }


TCP协议:【客户端和服务端】

  • 使用TCP协议前,须先建立TCP连接,形成传输数据通道
  • 传输前,采用“三次握手”方式,是可靠的
  • 在连接中可进行大数据量的传输
  • 传输完毕,需释放已建立的连接,效率低
  • 优点:可靠,安全,但是效率低。【每一次发送数据都要服务端确认】

UDP协议:【发送端和接收端】

  • 将数据、源、目的封装成数据包,不需要建立连接
  • 每个数据报的大小限制在64K内
  • 因无需连接,故是不可靠的
  • 发送数据结束时无需释放资源,速度快


套接字Socket 

端口号与IP地址的组合得出一个网络套接字。

  1. 通信的两端都要有Socket,是两台机器间通信的端点,网络通信其实就是Socket间的通信。
  2. Socket允许程序把网络连接当成一个流,数据在两个Socket间通过IO传输。
  3. 客户端和服务器现在可以通过对Socket对象的写入和读取来进行进行通信。

 ctrl+alt+T[try...catch],快速生成try...catch结构

Socket accept() throws IOException     
等待客户端的连接请求,返回与该客户端进行通信用的Socket对象

void close()throws IOException    
关闭监听Socket

打开连接到 Socket 的输入/出流
InputStream getInputStream()  throws IOException
获取与Socket相关联的字节输入流,用于从Socket中读数据。

OutputStream getOutputStream()  throws IOException
获取与Socket相关联的字节输出流,用于向Socket中写数据。

Socket java.net.Socket 和 ServerSocket java.net.ServerSocket

客户端要获取一个Socket对象通过实例化 ,而 服务器获得一个Socket对象则通过accept()方法的返回值

    //客户端
    @Test
    public void client() throws Exception {
        String str = "我在精神病院斩神";
        //当Socket构造方法返回,并没有简单的实例化了一个Socket对象,
        //它实际上会尝试连接到指定的服务器和端口
        Socket s = new Socket(InetAddress.getByName("localhost"), 9898);

        //发送数据给服务端
        OutputStream os = s.getOutputStream();
        os.write(str.getBytes());
        //发送完毕
        s.shutdownOutput();

        //接收服务端的反馈
        InputStream in = s.getInputStream();
        byte[] b = new byte[1024];
        int len = 0;
        while((len = in.read(b)) != -1){
            System.out.println(new String(b, 0, len));
        }
        in.close();
        os.close();
        s.close();
    }


    //服务端
    @Test
    public void server() throws IOException {
        //应用程序已经绑定到指定的端口,并且侦听客户端请求
        ServerSocket ss = new ServerSocket(9898);
        //该accept()方法将一直等待,直到客户端连接到服务器上给定的端口。
        Socket s = ss.accept();

        //接收客户端数据
        InputStream in = s.getInputStream();
        byte[] b = new byte[1024];
        int len = 0;
        while((len = in.read(b)) != -1){
            System.out.println(new String(b, 0, len));
        }

        //发送反馈给客户端
        OutputStream os = s.getOutputStream();
        os.write("成功接收数据".getBytes());

        os.close();
        in.close();
        s.close();
        ss.close();
    }

从客户端发送文件给服务端,服务端保存到本地。并返回“发送成功”给客户端。并关闭相应的连接

//3.从客户端发送文件给服务端,服务端保存到本地。并返回“发送成功”给客户端。并关闭相应的连接
public class FileTest {
    //客户端
    @Test
    public void client() throws IOException {
        Socket s = new Socket(InetAddress.getByName("192.168.15.86"), 9898);

        OutputStream os = s.getOutputStream();
        FileInputStream fis = new FileInputStream("./1.jpg");
        byte[] b = new byte[1024];
        int len = 0;
        while ((len = fis.read(b)) != -1) {
            os.write(b, 0, len);
        }

        //发送完毕
        s.shutdownOutput();

        //接收反馈
        InputStream in = s.getInputStream();
        while ((len = in.read(b)) != -1) {
            System.out.println(new String(b, 0, len));
        }

        in.close();
        fis.close();
        os.close();
        s.close();
    }

    //服务端
    @Test
    public void server() throws IOException {
        ServerSocket ss = new ServerSocket(9898);
       //处于阻塞,等待连接的那个Socket
        Socket s = ss.accept();
        //使用输出流FileOutputStream把图片保存到本地
        InputStream in = s.getInputStream();
        FileOutputStream fos = new FileOutputStream("./2.jpg");
        byte[] b = new byte[1024];
        int len = 0;
        while ((len = in.read(b)) != -1) {
            fos.write(b, 0, len);
        }
        //给客户端返回信息
        OutputStream os = s.getOutputStream();
        os.write("接收图片成功".getBytes());

        os.close();
        fos.close();
        in.close();
        s.close();
        ss.close();
    }
}

DatagramSocket与DatagramPacket
 java.net.DatagramPacket
系统不保证UDP数据报一定能够安全送到目的地,也不能确定什么时候可以抵达。

public class FileTest {
    //UDP发送端
    @Test
    public void client() throws IOException {
        //使用UDP协议传输
        DatagramSocket datagramSocket = new DatagramSocket();
        byte[] bytes="我在精神病院学斩神".getBytes(StandardCharsets.UTF_8);
        //DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port)
        //构造数据报包,用来将长度为 length 偏移量为 offset 的包发送到指定主机上的指定端口号。
        DatagramPacket p=new DatagramPacket(bytes,0,bytes.length, InetAddress.getByName("127.0.0.1"),9898);
        datagramSocket.send(p);
        datagramSocket.close();
    }

    //UDP接收端
    @Test
    public void server() throws IOException {
        //使用UDP协议传输
        DatagramSocket datagramSocket = new DatagramSocket(9898);
        byte[] bytes=new byte[1024];
        //DatagramPacket(byte[] buf, int length)
        //构造 DatagramPacket,用来接收长度为 length 的数据包。
        DatagramPacket p=new DatagramPacket(bytes,bytes.length);
        datagramSocket.receive(p);
        System.out.println(new String(p.getData(),0,p.getData().length));
        datagramSocket.close();
    }
}

java.net.URL

URL(Uniform Resource Locator):统一资源定位符,它表示 Internet 上某一资源的地址。

 URL的基本结构由5部分组成:
<传输协议>://<主机名>:<端口号>/<文件名>
例如: http://192.168.1.100:8080/helloworld/index.jsp

构造器:
URL(String spec) 
          根据 String 表示形式创建 URL 对象。
方法:
public final InputStream openStream() throws IOException
打开到此 URL 的连接并返回一个用于从该连接读入的 InputStream。


此方法是下面方法的缩写: openConnection().getInputStream()

public URLConnection openConnection() throws IOException
返回一个 URLConnection 对象,它表示到 URL 所引用的远程对象的连接。

//获取整个url结构
一个URL对象生成后,其属性是不能被改变的,但可以通过它给定的方法来获取这些属性

public String getProtocol(  )  ;//URL的协议名
public String getHost(  )  ;//该URL的主机名
public String getPort(  ) ;// 获取该URL的端口号
public String getPath(  )           获取该URL的文件路径
public String getFile(  )             获取该URL的文件名
public String getRef(  )             获取该URL在文件中的相对位置
public String getQuery(   )        获取该URL的查询名
    @Test
    public void test03() throws Exception {
//      通过一个表示URL地址的字符串可以构造一个URL对象
        URL url = new URL("http://192.168.15.55/atguigu/hello.txt");
//      InputStream in = url.openStream(); //openStream():能从网络上读取数据,获取指定站点的资源
        URLConnection connection = url.openConnection(); //不仅可以获取指定站点资源,还可以发送资源到指定站点
        InputStream in = connection.getInputStream();
        byte[] b = new byte[1024];
        int len = 0;
        while((len = in.read(b)) != -1){
            System.out.println(new String(b, 0, len));
        }
        in.close();
    }

java8 新特性[方法区,元空间]

jdk1.8把静态成员和常量池都放在了堆中,元空间放类加载信息

不同的jvm

  1. sun-hotspot
  2. oracle-jrocket
  3. IBM-j9
  4. TaoBaoJVM

为什么要用lambda表达式,底层用设计模式

//获取年龄大于18的职员
策略设计模式:

//创建一个Java文件,这里为了简单,省略set,get,全参构造器
public class Employee {

    private String name;
    private Integer age;
    private Double salary;
}

不使用策略模式之前,我们是像下面这样写的代码。遍历,进行筛选。每一个条件都会对应一个方法,好烦呢!

public class LambdaTest {

    //测试数据
    List employees = Arrays.asList(
            new Employee("张三", 18, 9999.99),
            new Employee("李四", 35, 3333.33),
            new Employee("王五", 20, 5555.55),
            new Employee("赵六", 8, 6666.66),
            new Employee("田七", 19, 8888.88)
    );

    //需求:获取所有年龄大于 18 的职员
    public List filterEmployeeByAge(List list){
        List emps = new ArrayList<>();
        for (Employee e : list) {
            if(e.getAge() > 18){
                emps.add(e);
            }
        }

        return emps;
    }

    //需求:获取所有工资大于 5000 的职员
    public List filterEmployeeBySalary(List list){
        List emps = new ArrayList<>();
        for (Employee e : list) {
            if(e.getSalary() > 5000){
                emps.add(e);
            }
        }

        return emps;
    }
}

体会策略模式,真是妙啊!!!!

public interface MyPredicate {

    public boolean test(T t);

}
    //策略设计模式
    public List filterEmployee(List list, MyPredicate mp){
        List emps = new ArrayList<>();

        for (Employee e : list) {
            if(mp.test(e)){
                emps.add(e);
            }
        }

        return emps;
    }

   //优化方式一:匿名内部类+匿名对象
    @Test
    public void test4(){
        List emps = filterEmployee(this.employees, new MyPredicate() {
            @Override
            public boolean test(Employee employee) {
                return employee.getAge() < 18;
            }
        });

        for (Employee emp : emps) {
            System.out.println(emp);
        }
    }


    //优化方式二:Java8的 Lambda 表达式
    @Test
    public void test5(){
        List emps = filterEmployee(this.employees, (e) -> e.getAge() > 18);

        for (Employee emp : emps) {
            System.out.println(emp);
        }
    }


    //优化方式三:Java8 的 Stream API
    @Test
    public void test6(){
        employees.stream().filter((e) -> e.getAge() > 18).forEach(System.out::println);

        System.out.println("-----------------------------------------");

        employees.stream().map(Employee::getName).skip(2).forEach(System.out::println);
    }
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/860869.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号