首页 > 其他分享 >【面试突击】网络通信面试实战

【面试突击】网络通信面试实战

时间:2024-02-07 12:32:56浏览次数:28  
标签:网络通信 实战 NIO BIO 面试 线程 IO Socket 客户端

网络通信面试实战

Socket 工作原理

Socket 是应用层与 TCP/IP 协议族通信的中间软件抽象层,它是一组接口,其实就是一个门面模式,将底层复杂的通信操作给封装起来对外提供接口。

简单来说就是 Socket 把 TPC/IP 协议给封装了起来,我们的程序进行网络通信都是通过 Socket 来完成的!

也就是说当两台设备进行通信时,是通过 Socket 进行通信的,接下来通过 Java 代码来了解一下如何通过 Socket 进行网络通信:

服务端:

public class Server {
    public static void main(String[] args) {
        int port = 1234; // 服务器监听的端口号

        try (ServerSocket serverSocket = new ServerSocket(port)) {
            System.out.println("服务器启动,等待客户端连接...");

            // 等待客户端连接
            Socket clientSocket = serverSocket.accept();
            System.out.println("客户端已连接:" + clientSocket.getInetAddress().getHostAddress());

            // 获取输入流
            InputStream input = clientSocket.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(input));

            // 读取客户端发送的消息
            String received = reader.readLine();
            System.out.println("接收到消息: " + received);

            // 获取输出流
            OutputStream output = clientSocket.getOutputStream();
            PrintWriter writer = new PrintWriter(output, true);

            // 回显客户端发送的消息
            writer.println("服务器回显: " + received);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


客户端:

public class Client {
    public static void main(String[] args) {
        String serverAddress = "localhost"; // 服务器地址
        int port = 1234; // 服务器监听的端口号

        try (Socket socket = new Socket(serverAddress, port)) {
            System.out.println("连接到服务器...");

            // 获取输出流
            OutputStream output = socket.getOutputStream();
            PrintWriter writer = new PrintWriter(output, true);

            // 向服务器发送消息
            writer.println("Hello, Server!");

            // 获取输入流
            InputStream input = socket.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(input));

            // 读取服务器回显的消息
            String response = reader.readLine();
            System.out.println("接收到服务器的回显: " + response);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}



BIO、NIO和AIO

面试中问到网络相关的内容,其中 BIO、NIO 的内容肯定是必问的,AIO 可以了解一下,一定要清楚 BIO 和 NIO 中通信的流程

我也画了两张图,可以记下这两张图

  • AIO:

从 Java.1.7 开始,Java 提供了 AIO(异步IO),Java 的 AIO 也被称为 “NIO.2”

Java AIO 采用订阅-通知模式,应用程序向操作系统注册 IO 监听,之后继续做自己的事情,当操作系统发生 IO 事件并且已经准备好数据时,主动通知应用程序,应用程序再进行相关处理

(Linux 平台没有这种异步 IO 技术,而是使用 epoll 对异步 IO 进行模拟)


  • BIO:

BIO 即同步阻塞 IO,服务端实现模式为一个连接对应一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理

BIO简单工作流程:

  1. 服务器端启动一个 ServerSocket,用于接收客户端的连接
  2. 客户端启动 Socket 与服务器建立连接,默认情况下服务器端需要对每个客户端建立一个线程与之通讯(并且与每一个可u后端有一个对应的 Socket)
  3. 客户端发出请求后, 先咨询服务器是否有线程响应,如果没有则会等待,或者被拒绝
  4. 如果服务端有对应线程处理
  • 客户端进行读取,则线程会被阻塞直到完成读取
  • 客户端进行写入,则线程会被阻塞直到完成写入

使用 BIO 通信的流程图如下:

【面试突击】网络通信面试实战_数据


BIO存在问题:

  1. 当并发量较大时,需要创建大量线程来处理连接,比较占用系统资源
  2. 连接建立之后,如果当前线程暂时没有数据可读,则线程会阻塞在 Read 操作上,造成线程资源浪费
  • NIO:

从 Java1.4 开始,Java 提供了 NIO,NIO 即 “Non-blocking IO”(同步非阻塞IO)

NIO 的几个核心概念:

  1. Channel、Buffer:BIO是基于字节流或者字符流的进行操作,而NIO 是基于缓冲区通道进行操作的,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中
  2. Selector:选择器用于监听多个通道的事件(如,连接打开,数据到达),因此,单个线程可以监听多个数据通道,极大提升了单机的并发能力
    当 Channel 上的 IO 事件未到达时,线程会在 select 方法被挂起,让出 CPU 资源,直到监听到 Channel 有 IO 事件发生,才会进行相应的处理
  • NIO和BIO有什么区别?
  1. NIO是以的方式处理数据,BIO是以字节流或者字符流的形式去处理数据。
  2. NIO是通过缓存区和通道的方式处理数据,BIO是通过InputStream和OutputStream流的方式处理数据。
  3. NIO的通道是双向的,BIO流的方向只能是单向的。
  4. NIO采用的多路复用的同步非阻塞IO模型,BIO采用的是普通的同步阻塞IO模型。
  5. NIO的效率比BIO要高,NIO适用于网络IO,BIO适用于文件IO。

NIO如何实现了同步非阻塞?

通过 Selector 和 Channel 来进行实现,一个线程使用一个 Selector 监听多个 Channel 上的 IO 事件,通过配置监听的通道Channel为非阻塞,那么当Channel上的IO事件还未到达时,线程会在select方法被挂起,让出CPU资源。直到监听到Channel有IO事件发生时,才会进行相应的响应和处理。


使用 NIO 通信的流程图如下:

【面试突击】网络通信面试实战_客户端_02





标签:网络通信,实战,NIO,BIO,面试,线程,IO,Socket,客户端
From: https://blog.51cto.com/u_16186397/9636178

相关文章

  • 面试经典 150 题 (十二)
    排序,i代表至少发表的论文数量时间复杂度:O(nlogn)空间复杂度:O(logn)classSolution{publicinthIndex(int[]citations){//01356intlength=citations.length;Arrays.sort(citations);inth=0;for(inti=1......
  • 解锁阿里巴巴面试题:创建线程的几种方式?
    大家好,我是小米!今天我们来聊一个热门话题——阿里巴巴面试题:创建线程的几种方式。在技术的海洋中,线程是我们编程航程中的一艘不可或缺的船,驶向程序的未知领域。那么,究竟有哪些方式可以创建线程呢?让我们一起揭开这个技术的神秘面纱!实现Runnable接口首先,我们来说说最常见、最推荐的方......
  • C语言解题 || 公务员面试
    题目:公务员面试现场打分。有7位考官,从键盘输入若干组成绩,每组7个分数(百分制),去掉一个最分和一个最低分,输出每组的平均成绩。(注:本题有多组输入)输入描述:每一行,输入7个整数(0~100),代表7个成绩,用空格分隔。输出描述:每一行,输出去掉最高分和最低分的平均成绩,小数点后保留2位......
  • 面试经典:Java中list set map之间的区别
    前言大家好,我是chowley,最近正在复习Java集合,这次来总结一下list、set、map它们三个之间的区别。1.List(列表)定义:List是一种有序集合,允许存储重复元素,每个元素都有一个索引,可以按照插入顺序获取。特点:允许存储重复元素。有序集合,保留元素的插入顺序。可以通过索引访问元素。常见实现......
  • 计算机网络抓包实战
    介绍计算机网络作为一门计算机专业课,平时都是各种抽象的协议和各种发送接收,很难具体的去感受其含义,因此也是借助wireshark对发送的包进行一个分析。抓包分析三次握手验证在第一次访问到182.254.242.96这个ip时,首先是建立了TCP的三次握手。与书上写的一样:客户端发起握手请求......
  • 梅科尔工作室HOS-鸿蒙开发实战(深呼吸)
    页面整体展示效果源码importhttpfrom'@ohos.net.http'@Entry@Componentstructjieya{textTimerController:TextTimerController=newTextTimerController()@StateisTimerRunning:boolean=true//新增一个状态变量来表示计时器运行状......
  • Docker Arthas 实战指南
    Arthas是一款强大的Java诊断和调试工具,它能够在生产环境中实时诊断Java应用,提供强大的调试功能,帮助开发者和运维人员解决各种Java应用的性能问题和调试挑战。本指南将介绍如何在Docker环境中使用Arthas进行实战。官方文档GitHub地址gitee地址应用场景性能分析与优化:Art......
  • 面试经典 150 题 (十一)
    classSolution{publicintjump(int[]nums){if(nums.length<=1)return0;//记录每次起跳所能跳到的最远的距离intfarestIndex=0;intmaxIndex=0;intstart=0;inttimes=0;while(true){......
  • 【面试突击】数据库面试实战-SQL 优化(加更)
    欢迎关注公众号【11来了】,及时收到AI前沿项目工具及新技术的推送!在我后台回复「资料」可领取编程高频电子书!在我后台回复「面试」可领取硬核面试笔记!MySQL中的SQL优化这里主要说一下MySQL中如何对SQL进行优化,其实主要还是根据索引来进行优化的,如果好好了解下边的SQL......
  • 服务器-Kubernetes (K8S)单机部署实战 -- 001
       本篇博文是centos7系统安装kubernetes单机master节点操作。一:查看服务器配置信息   1.执行命令查看服务器cpu信息。安装kubernetes服务,cpu核心数必须大于2,内存大于2G。lscpu   2. 修改服务器设置信息,避免安装出现问题。    a.......