欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程语言 > java >内容正文

java

你对Java网络编程了解的如何?Java BIO 网络编程 | Netty 前期知识

发布时间:2025/3/19 java 49 豆豆
生活随笔 收集整理的这篇文章主要介绍了 你对Java网络编程了解的如何?Java BIO 网络编程 | Netty 前期知识 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

一步一步走来,之前去学习了JUC并发编程知识,现在终于到Java IO网络编程啦,难啊。

一、BIO介绍

引入: 随着技术的发展,两个或以上的程序必然需要进行交互,于是提供了一种端到端的通信,相当于对传输层的一种封装,对于开发人员而言隐藏了传输的细节,将这些固定的“套路”抽象出来,提供一种端到端的通信,可以使我们更加专注于业务的开发。而BIO只是其中一种。

Java BIO (old )就是传统的 Java I/O 编程,其相关的类和接口在 java.io,另外Java BIO是同步并阻塞(传统阻塞型),服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理。效率较低,资源容易被浪费。

阻塞和非阻塞

阻塞和非阻塞指的是执行一个操作是等操作结束再返回,还是马上返回。

比如餐馆的服务员为用户点菜,当有用户点完菜后,服务员将菜单给后台厨师,此时有两种方式:

  • 第一种:就在出菜窗口等待,直到厨师炒完菜后将菜送到窗口,然后服务员再将菜送到用户手中;(阻塞方式)
  • 第二种:等一会再到窗口来问厨师,某个菜好了没?如果没有先处理其他事情,等会再去问一次;(非阻塞的)

二、BIO模型

流程分析:

  • 首先需要启动一个ServerSocket服务端,用来供客户端连接
  • 然后再启动ClientSocket客户端,与服务器进行连接通信。(注:默认情况下,每个客户端与服务端都是单独的一个线程通信,不管使用不使用)
  • 在客户端发出请求后,会先询问服务器端是否可以有线程响应,有以下两种结果:
    • 如若有线程响应,客户端会阻塞等待请求结束后,再继续执行;
    • 假如没有线程响应则会等待响应,或者直接被拒绝
  • 三、代码案例

    1)案例:

    我们使用BIO模型写一个服务器端,监听8888端口,当有客户端连接时,就启动一个线程与它通讯。

    编程思路:

  • 创建一个线程池
  • 创建ServerSocket对象 服务器套接字(ServerSocket)等待通过网络传入的请求。
  • 如果有客户端连接,就创建一个线程,与之通讯(单独写一个方法)
  • 获得Socket对象, 用于连接通信
  • 编写一个handler方法,和客户端通讯,读取客户端发过来的信息
  • package com.crush.bio;import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.*;/*** @Author: crush* @Date: 2021-08-23 11:51* version 1.0c*/ public class BioServer {public static void main(String[] args) throws Exception {//1. 创建一个线程池ExecutorService newCachedThreadPool = new ThreadPoolExecutor(0,Integer.MAX_VALUE,60L,TimeUnit.SECONDS,new SynchronousQueue<>(),Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());//2、创建ServerSocketServerSocket serverSocket = new ServerSocket(8888);System.out.println("服务器启动了");while (true) {System.out.println("线程信息id = " + Thread.currentThread().getId() + "名字 = " + Thread.currentThread().getName());//监听,等待客户端连接System.out.println("等待连接....");//3.侦听要与此套接字建立的连接并接受它。 该方法阻塞,直到建立连接。final Socket socket = serverSocket.accept();System.out.println("连接到一个客户端");//4、就创建一个线程,与之通讯(单独写一个方法)newCachedThreadPool.execute(() -> {//可以和客户端通讯handler(socket);});}}/*** 编写一个handler方法,和客户端通讯,读取客户端发过来的信息* @param socket*/public static void handler(Socket socket) {try {System.out.println("线程信息id = " + Thread.currentThread().getId() + "名字 = " + Thread.currentThread().getName());byte[] bytes = new byte[1024];//通过socket获取输入流InputStream inputStream = socket.getInputStream();//循环的读取客户端发送的数据while (true) {System.out.println("线程信息id = " + Thread.currentThread().getId() + "名字 = " + Thread.currentThread().getName());System.out.println("read....");int read = inputStream.read(bytes);if (read != -1) {//输出客户端发送的数据System.out.println(new String(bytes, 0, read));} else {break;}}} catch (Exception e) {e.printStackTrace();} finally {System.out.println("关闭和client的连接");try {socket.close();} catch (Exception e) {e.printStackTrace();}}} }

    这是一个经典的每连接每线程的模型,之所以使用多线程,主要原因在于socket.accept()、socket.read()、socket.write()三个主要函数都是同步阻塞的,当一个连接在处理I/O的时候,系统是阻塞的,如果是单线程的话必然就挂死在那里;但CPU是被释放出来的,开启多线程,就可以让CPU去处理更多的事情。

    2)测试步骤:

  • 打开cmd命令输入telnet localhost 8888

  • 会进入到telnet页面

  • 然后在telnet 命令窗口中按下 CTRL+]

  • 发送信息命令 是 send 信息

  • 控制台输出


  • 客户端

    客户端我也有写的哈😁

    package com.crush.bio;import java.io.PrintStream; import java.net.Socket; import java.util.Scanner;public class BIOEchoClient {public static void main(String[] args) throws Exception{Socket client = new Socket("localhost",8888);PrintStream out = new PrintStream(client.getOutputStream());boolean flag = true;while (flag){Scanner scanner = new Scanner(System.in);String inputData = scanner.nextLine().trim();out.println(inputData);if ("byebye".equalsIgnoreCase(inputData)){flag = false;System.out.println("和客户端说再见拉!!!");}}client.close();} }

    这个测试就不说了哈,这个蛮简单的。

    3)可能会出现的问题

    我们使用telnet命令来测试,默认Windows这个命令是关闭的,就会出现和我一样的问题。

    打开方式:打开控制面板,点程序,然后再点这个进行选择。

    四、BIO存在的缺陷

    BIO的最大缺陷就是在于每个请求都需要创建独立的线程进行连接通讯,这样会造成以下几点问题:

  • 当并发数上升到较大的时候,需要创建大量线程来处理,容易给系统造成极大的压力,其次创建太多线程、销毁太多线程,占用系统资源较大。
  • 如果建立连接后,当前线程任务较小,较短,然后之后没有数据可读,则线程会一直阻塞在Read操作上,造成资源的浪费。
  • 五、自言自语

    最近在持续更新中,如果你觉得对你有所帮助,也感兴趣的话,关注我吧,让我们一起学习,一起讨论吧。

    在学习路上充满好奇心,明白思考的重要性,是支持我一直学习下去的积极推动力吧。希望你也能喜欢上编程!😁

    热爱生活,享受生活!!!无论在哪里,无论此时的生活多么艰难,都要记得热爱生活!!!相信总会有光来的。

    你好,我是博主宁在春,Java学习路上的一颗小小的种子,也希望有一天能扎根长成苍天大树。

    希望与君共勉😁

    我们:待别时相见时,都已有所成

    总结

    以上是生活随笔为你收集整理的你对Java网络编程了解的如何?Java BIO 网络编程 | Netty 前期知识的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。