当前位置: 首页 > news >正文

java网络通信(三):TCP通信、实现客户端-服务端消息通信

目录

1、什么是 TCP协议?

2、代码实现TCP协议的一发一收

2.1、客户端

2.2、服务端

2.3 结果演示

3、代码实现TCP协议的多发多收

3.1 客户端

3.2 服务端

3.3 结果演示


简介:本文章主要是演示如何用java代码以及TCP协议实现网络通信,实现客户端给服务端发送消息,服务端接收消息的功能。以及用代码演示如何手动输入消息并发送给服务端(类似聊天软件)。

不了解通信的同学可以先看看我上一篇发的文章,很详细

java网络通信(一):BS架构、CS架构、IP地址、端口号、协议、域名等基础概念,以及代码演示-CSDN博客

1、什么是 TCP协议?

面向连接、可靠通信

三次握手:建立可靠的连接,相当于客户端和服务器生成了一条端对端的管道、可以互相通信。

传输数据时会进行确认,例如客户端发信息给服务端,服务端收到消息后会进行确认,表示已经收到信息。若没有确认,则说明消息服务端并没有收到,则需要客户端再次发送,以此来保证数据传输的可靠性。

四次挥手:在断开连接的时候保证彼此的信息都收发完毕

2、代码实现TCP协议的一发一收

我们的TCP协议实现网络通信中,是端到端的,相当于两个端点形成了一条管道,相互传输数据,十分安全。

2.1、客户端

注意看注释

public class TCP_OneToOne_Clint {public static void main(String[] args) throws Exception {//1、创建Socket对象,并同时请求于服务端程序的连接Socket socket = new Socket("127.0.0.1",8888);//2、从socket得到一个字节输出流,用来发送数据给服务端OutputStream outputStream = socket.getOutputStream();//3、把低级的字节输出流包装成数据输出流DataOutputStream dataOutputStream = new DataOutputStream(outputStream);//4、开始写数据出去dataOutputStream.writeUTF("你好,我是TCP协议客户端发来的消息!");System.out.println("我是客户端,已发送消息");dataOutputStream.close();//5、关闭资源socket.close();;}
}

2.2、服务端

服务端:serverSocket等待客户端的链接请求,以便建立于客户端的通信管道

accept一但链接成功,就会形成一个可靠的连接通信管道。同时也会返回服务端的socket对象,这样服务端就可以拿到这个socket对象和客户端进行通信了

客户端程序执行到accept的时候,在等待客户端发送请求,一但接收到客户端的请求,就连接成功生成通信管道,且是端到端的,

流的格式一定是客户端和服务端一一对应,通信是非常严格的,否则会出问题。(比如客户端用的是数据流发消息,那么服务端就一定要用数据流读消息)

解释:客户端newSocket的时候,服务端的accept方法就会连接上

public class TCP_OneToOne_Server {public static void main(String[] args) throws Exception {System.out.println("服务端启动,等待客户端发送消息");//1、创建ServerSocket的对象,同时为服务端注册端口ServerSocket serverSocket = new ServerSocket(8888);//2、使用ServerSocket对象,调用一个accept方法,等待客户端的连接请求Socket socket = serverSocket.accept();//3、从通信管道中得到一个字节输入流InputStream inputStream = socket.getInputStream();//4、使用数据输入流包装成输入流(注意必须和客户端的一致)DataInputStream dataInputStream = new DataInputStream(inputStream);//5、使用数据输入流读取客户端发来的消息//当客户端消息还没发来,就会在这一步进行等待(如果客户端先发送信息来,服务端还没读取,没关系,客户端会先把消息缓存起来的// 因为是TCP可靠通信,是一定会保证消息被读取的)System.out.println(dataInputStream.readUTF());//获取客户端的IP地址System.out.println(socket.getRemoteSocketAddress());//6、关闭资源dataInputStream.close();socket.close();}
}

2.3 结果演示

第一步启动服务端

在客户端还没启动之前,服务端一直在等待客户端的消息

第二步启动客户端:

可以看到客户端将消息发送出去了

再回到服务端看日,可以看到服务端接收到了客户端的消息!

3、代码实现TCP协议的多发多收

3.1 客户端

public class TCP_Many_Clint {public static void main(String[] args) throws Exception {//1、创建Socket对象,并同时请求于服务端程序的连接Socket socket = new Socket("127.0.0.1",8888);//2、从socket得到一个字节输出流,用来发送数据给服务端OutputStream outputStream = socket.getOutputStream();//3、把低级的字节输出流包装成数据输出流DataOutputStream dataOutputStream = new DataOutputStream(outputStream);Scanner scanner = new Scanner(System.in);while (true){System.out.println("请说:");String msg = scanner.nextLine();if ("exit".equals(msg)){System.out.println("客户端下线!");dataOutputStream.close();//5、关闭资源socket.close();;break;}dataOutputStream.writeUTF(msg);System.out.println("我是客户端,已给服务端发送消息");}}
}

3.2 服务端

当客户端exit了,服务端就会报错,因为read不到数据了,所以我们可以加一个捕获异常,当读取信息报错时,说明客户端离线了

public class TCP_Many_Server {public static void main(String[] args) throws Exception {System.out.println("服务端启动,等待客户端发送消息");//1、创建ServerSocket的对象,同时为服务端注册端口ServerSocket serverSocket = new ServerSocket(8888);//2、使用ServerSocket对象,调用一个accept方法,等待客户端的连接请求Socket socket = serverSocket.accept();//3、从通信管道中得到一个字节输入流InputStream inputStream = socket.getInputStream();//4、使用数据输入流包装成输入流(注意必须和客户端的一致)DataInputStream dataInputStream = new DataInputStream(inputStream);while (true){try {System.out.println(dataInputStream.readUTF());System.out.println(socket.getRemoteSocketAddress());}catch (Exception e){//6、关闭资源System.out.println(socket.getRemoteSocketAddress() + "客户端下线!");dataInputStream.close();socket.close();break;}}}
}

3.3 结果演示

第一步启动服务端

在客户端还没启动之前,服务端一直在等待客户端的消息

第二步启动客户端:

输入想要发送的消息。按回车

在服务端就可以看到我们手动在客户端命令行输入的消息了

这就是我对javaTCP通信相关的理解,希望能帮到大家,有问题的地方欢迎大家一起讨论!

后续会不断更新作品,欢迎大家一起讨论学习。❤❤❤

相关文章:

java网络通信(三):TCP通信、实现客户端-服务端消息通信

目录 1、什么是 TCP协议? 2、代码实现TCP协议的一发一收 2.1、客户端 2.2、服务端 2.3 结果演示 3、代码实现TCP协议的多发多收 3.1 客户端 3.2 服务端 3.3 结果演示 简介:本文章主要是演示如何用java代码以及TCP协议实现网络通信,实…...

mybatis-plus 对于属性为null字段不更新

MyBatis-Plus 默认情况下会根据字段的值是否为 null 来决定是否生成对应的 UPDATE 语句。这是由 更新策略 决定的,默认的行为是 忽略 null 值,即如果字段值为 null,该字段将不会出现在 UPDATE 语句中。 默认行为分析 MyBatis-Plus 默认的 Fi…...

GAGAvatar: Generalizable and Animatable Gaussian Head Avatar 学习笔记

1 Overall GAGAvatar(Generalizable and Animatable Gaussian Avatar),一种面向单张图片驱动的可动画化头部头像重建的方法,解决了现有方法在渲染效率和泛化能力上的局限。 旋转参数 现有方法的局限性: 基于NeRF的方…...

《数据挖掘:概念、模型、方法与算法(第三版)》

嘿,数据挖掘的小伙伴们!今天我要给你们介绍一本超级实用的书——《数据挖掘:概念、模型、方法与算法》第三版。这本书是数据挖掘领域的经典之作,由该领域的知名专家编写,系统性地介绍了在高维数据空间中分析和提取大量…...

springboot vue 开源 会员收银系统 (12)购物车关联服务人员 订单计算提成

前言 完整版演示 http://120.26.95.195/ 开发版演示 http://120.26.95.195:8889/ 在之前的开发进程中,我们完成订单的挂单和取单功能,今天我们完成购物车关联服务人员,用户计算门店服务人员的提成。 1.商品关联服务人员 服务人员可以选择 一…...

lua闭包Upvalue

闭包 lua任何函数都是闭包,闭包至少带1个upValue; CClosure是使用Lua提供的lua_pushcclosure这个C-Api加入到虚拟栈中的C函数,它是对LClosure的一种C模拟 如string.gmatch就是cclosure 定义: #define ClosureHeader \CommonH…...

下载maven 3.6.3并校验文件做md5或SHA512校验

一、下载Apache Maven 3.6.3 Apache Maven 3.6.3 官方下载链接: 二进制压缩包(推荐): ZIP格式: https://archive.apache.org/dist/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.zipTAR.GZ格式: https://archive.apache.org/dist/…...

深入探索Flax:一个用于构建神经网络的灵活和高效库

深入探索Flax:一个用于构建神经网络的灵活和高效库 在深度学习领域,TensorFlow 和 PyTorch 作为主流的框架,已被广泛使用。不过,Flax 作为一个较新的库,近年来得到了越来越多的关注。Flax 是一个由Google Research团队…...

vue项目中单独文件的js不存在this.$store?.state怎么办

在Vue项目中,如果你在单独的文件(比如插件、工具函数等)中遇到this.$store不存在的情况,这通常是因为this上下文不指向Vue实例,或者Vuex store没有被正确地注入到Vue实例中。以下是几种可能的解决方案: 确保…...

物联网客户端在线服务中心(客服功能/私聊/群聊/下发指令等功能)

一、界面 私聊功能(下发通知类,一对多)群聊(点对点)发送指令(配合使用客户端,基于cefsharp做的物联网浏览器客户端)修改远程参数配置(直接保存到本地)&#…...

AI开发:逻辑回归 - 实战演练- 垃圾邮件的识别(二)

接上一篇AI开发:逻辑回归 - 实战演练- 垃圾邮件的识别(一) new_email 无论为什么文本,识别结果几乎都是垃圾邮件,因此我们需要对源码的逻辑进行梳理一下: 在代码中,new_email 无论赋值为何内容都被识别为…...

hint: Updates were rejected because the tip of your current branch is behind!

问题 本地仓库往远段仓库推代码时候提示: error: failed to push some refs to 192.168.2.1:java-base/java-cloud.git hint: Updates were rejected because the tip of your current branch is behind! refs/heads/master:refs/heads/master [rejected] (…...

Vue的数据驱动原理

文章目录 什么是数据驱动那么vuejs是如何实现这种数据驱动的呢?对getter/setter的理解?一个简单的演示例子vue数据驱动原理是:采用数据劫持结合发布者和订阅者模式,通过“object.defineproperty()”来劫持各个属性的setter、getter,在数据变动时发布消息给订阅者,触发相应…...

【Db First】.NET开源 ORM 框架 SqlSugar 系列

.NET开源 ORM 框架 SqlSugar 系列 【开篇】.NET开源 ORM 框架 SqlSugar 系列【入门必看】.NET开源 ORM 框架 SqlSugar 系列【实体配置】.NET开源 ORM 框架 SqlSugar 系列【Db First】.NET开源 ORM 框架 SqlSugar 系列【Code First】.NET开源 ORM 框架 SqlSugar 系列【数据事务…...

数据分析-52-时间序列分解之变分模态分解VMD

文章目录 1 时间序列模态分解1.1 模态分解的概念1.2 模态分解的作用1.3 常用的模态分解方法1.4 模态分解的常用库2 变分模态分解VMD2.1 VMD的流程2.2 加载数据集2.2.1 数据重采样2.2.2 原始数据可视化2.3 VMD变分模态分解3 参考附录1 时间序列模态分解 1.1 模态分解的概念 时…...

做异端中的异端 -- Emacs裸奔之路4: 你不需要IDE

确切地说,你不需要在IDE里面编写或者阅读代码。 IDE用于Render资源文件比较合适,但处理文本,并不划算。 这的文本文件,包括源代码,配置文件,文档等非二进制文件。 先说说IDE带的便利: 函数或者变量的自动…...

redhat 7.9配置阿里云yum源

1、mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/backup/ 2、添加dns vim/etc/resolv.conf nameserver 8.8.8.8 nameserver 8.8.4.4 nameserver 114.114.114.114 #配置完先检查下通不通 3、vi /etc/yum/pluginconf.d/subscription-manager.conf # 将 “enabled1” 改为 “ena…...

简单快速的上手python

前言 python是一门可以快速上手的语言,原因是它语法简单,api容易使用自由灵活 当我们需要安装任何的三方库时,只需要执行 pip install XX 之后在代码里面import xxx就可以使用python啦。 并且python的代码自由灵活,使用缩进区…...

PHP和GD如何给图片添加模糊边缘效果

在PHP中,使用GD库给图片添加模糊边缘效果通常涉及几个步骤,包括加载图片、创建模糊效果、应用边缘处理以及保存结果图片。然而,GD库本身并不直接提供边缘模糊的函数,但你可以通过一些技巧来实现类似的效果。 以下是一个简化的步骤…...

PowerShell:查找并关闭打开的文件

Get-SmbOpenFile 打开 Windows PowerShell 并运行 Get-SmbOpenFile | Format-List 若要仅显示特定文件共享的连接,请使用 Where-Object 运行 Get-SmbOpenFile。 Get-SmbOpenFile | Where-Object Path -eq "C:\Data\" | Format-List Get-SmbSession 显…...

SQL进阶技巧:非等值连接--单向近距离匹配

目录 0 场景描述 1 数据准备 2 问题分析 ​编辑 ​编辑 3 小结 数字化建设通关指南 0 场景描述 表 t_1 和表 t_2 通过 a 和 b 关联时,有相等的取相等的值匹配,不相等时每一 个 a 的值在 b 中找差值最小的来匹。 表 t_1:a 中无重复值 表 t_1:a 中无重复值 a 1 2 4 …...

【golang】单元测试,以及出现undefined时的解决方案

单元测试 要对某一方法进行测试时,例如如下这一简单减法函数,选中函数名后右键->转到->测试 1)Empty test file 就是一个空文件,我们可以自己写测试的逻辑 但是直接点绿色箭头运行会出问题: 找不到包。我们要在…...

代理IP地址的含义与设置指南‌

在数字化时代,互联网已经成为我们日常生活不可或缺的一部分。然而,在享受互联网带来的便利的同时,我们也面临着隐私泄露、访问限制等问题。代理IP地址作为一种有效的网络工具,能够帮助我们解决这些问题。本文将详细介绍代理IP地址…...

Qt 2D绘图之三:绘制文字、路径、图像、复合模式

参考文章链接: Qt 2D绘图之三:绘制文字、路径、图像、复合模式 绘制文字 除了绘制图形以外,还可以使用QPainter::darwText()函数来绘制文字,也可以使用QPainter::setFont()设置文字所使用的字体,使用QPainter::fontInfo()函数可以获取字体的信息,它返回QFontInfo类对象…...

el-table 纵向 横向 多级表头

<el-table :data"tableData" class"diaTable":span-method"handleSpanMethod"border:header-cell-style"{background:#292929,color:#fff}"><!-- 纵向表头 --><el-table-column label"纵向表头" width"…...

linux perf安装问题解决

WARNING: perf not found for kernel 4.15.0-39 perf安装问题 perf是一个功能强大的linux性能分析工具&#xff0c;其功能依赖于内核&#xff0c;安装perf工具的版本必须与内核版本保持一致。 perf安装问题 使用apt 安装 perf包&#xff0c;运行时提示要安装与内核版本相一致…...

嵌入式Linux无窗口系统下搭建 Qt 开发环境

嵌入式Linux无窗口系统下搭建 Qt 开发环境 本文将介绍如何在树莓派的嵌入式 Linux 环境下&#xff0c;搭建 Qt 开发环境&#xff0c;实现无窗口系统模式&#xff08;framebuffer&#xff09;下的图形程序开发。 1. 安装 Qt 环境 接下来&#xff0c;安装核心 Qt 开发库以及与 …...

JSON vs 表单格式:两种常见请求格式的区别与应用

搞iOS UI 自动化的同时涉及到了给后端发送请求&#xff0c;请求数据的格式常用的有json格式和表单格式&#xff0c;这两种格式如何区分&#xff0c;如何使用&#xff0c;特此总结了一下。 表单格式&#xff08;Form Data&#xff09; 传统的 HTML 表单使用的请求体格式&#…...

通过torch.utils.data.DataLoader可提高深度学习的10倍运行的速度?

引言 在深度学习的训练过程中&#xff0c;数据加载是一个关键步骤&#xff0c;它直接影响到模型训练的效率。为了提高运行速度&#xff0c;我们通常会采用多种方法&#xff0c;比如数据预处理、多线程加载、缓存策略等。然而&#xff0c;有一个经常被忽视的优化点——调整torc…...

【QT】背景,安装和介绍

TOC 目录 背景 GUI技术 QT的安装 使用流程 QT程序介绍 main.cpp​编辑 Wiget.h Widget.cpp form file .pro文件 临时文件 C作为一门比较古老的语言&#xff0c;在人们的认知里始终是以底层&#xff0c;复杂和高性能著称&#xff0c;所以在很多高性能需求的场景之下…...

计算机网络:IP协议详细讲解

目录 前言 一、IP网段划分 二、IP报头 三、解决IP地址不足-->NAT技术 前言 在之前&#xff0c;我们学习了传输层中的TCP和UDP&#xff0c;重点是TCP协议&#xff0c;他帮我们解决具体到主机的哪个应用&#xff08;端口&#xff09;、传输的可靠&#xff08;序列号、校验和…...

Python中使用pip换源的详细指南

在Python开发过程中&#xff0c;我们经常需要安装各种第三方库。pip是Python的包管理工具&#xff0c;用于安装和管理Python库。然而&#xff0c;由于网络原因&#xff0c;有时访问默认的Python包索引&#xff08;PyPI&#xff09;可能会比较慢。这时&#xff0c;我们可以通过更…...

【Unity】WebGL全屏问题

1 前言 WebGL项目打包时不可避免的需要面对全屏化问题&#xff0c;或者说是占满网页的问题。这里讨论一下此问题。 2 全屏化 2.1 打包模板 WebGL在打包时可以选择不同的打包模板&#xff0c;其会影响最终打包好的项目在网页中的展现形式。可以在“Project Setting/Player/Set…...

基于大数据python 电商数据分析及推荐可视化系统(源码+LW+部署讲解+数据库+ppt)

&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 很对人不知道选题怎么选 不清楚自己适合做哪块内容 都可以免费来问我 避免后期給自己答辩找麻烦 增加难度&#xff08;部分学校只有一次答辩机会 没弄好就延迟…...

基于大数据python 热门微博数据分析可视化系统(源码+LW+部署讲解+数据库+ppt)

&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 很对人不知道选题怎么选 不清楚自己适合做哪块内容 都可以免费来问我 避免后期給自己答辩找麻烦 增加难度&#xff08;部分学校只有一次答辩机会 没弄好就延迟…...

MATLAB R2024b软件下载安装教程

软件版本: MATLAB R2024b 软件大小&#xff1a;24G 安装环境&#xff1a;Windows 10/11&#xff08;64位&#xff09; 界面语言&#xff1a;简体中文 软件下载&#xff1a;https://pan.xunlei.com/s/VOCut9-UJcX7k3AO7IGXobAiA1?pwdkqkr# 软件参考安装教程 1、使用网盘…...

机器学习算法(六)---逻辑回归

常见的十大机器学习算法&#xff1a; 机器学习算法&#xff08;一&#xff09;—决策树 机器学习算法&#xff08;二&#xff09;—支持向量机SVM 机器学习算法&#xff08;三&#xff09;—K近邻 机器学习算法&#xff08;四&#xff09;—集成算法 机器学习算法&#xff08;五…...

Pareidoscope - 语言结构关联工具

文章目录 关于 Pareidoscope安装使用方法输入格式语料库查询 将语料库转换为 SQLite3 数据库两种语言结构之间的关联简单词素分析关联共现和伴随词素分析相关的更大结构可视化关联结构 关于 Pareidoscope Pareidoscope 是一组 用于确定任意语言结构之间 关联的工具&#xff0c…...

Java中 HttpURLConnection 和 HttpClient 详解(初学者友好)

Java中HttpURLConnection和HttpClient详解&#xff08;初学者友好&#xff09; 在Java开发中&#xff0c;向服务器发送HTTP请求是常见的需求&#xff0c;比如调用API接口或获取远程数据。在JDK中&#xff0c;主要有两种方式实现HTTP通信&#xff1a; 使用 HttpURLConnection&…...

vulnhub-LUPINONE-靶场复盘-题解

靶机的下载连接https://download.vulnhub.com./empire/01-Empire-Lupin-One.zip 下载镜像后解压&#xff0c;然后导入到vmware中&#xff0c;使用的是nat模式 kali的ip地址&#xff1a;10.10.1.128 靶机ip地址&#xff1a;10.10.1.135 1.扫描靶机ip地址 命令&#xff1a;n…...

diff算法

vue的diff算法详解 vue&#xff1a; diff 算法是一种通过同层的树节点进行比较的高效算法 其有两个特点&#xff1a; 比较只会在同层级进行, 不会跨层级比较 在diff比较的过程中&#xff0c;循环从两边向中间比较 diff 算法在很多场景下都有应用&#xff0c;在 vue 中&…...

通过异步使用消息队列优化秒杀

通过异步使用消息队列优化秒杀 同步秒杀流程异步优化秒杀异步秒杀流程基于lua脚本保证Redis操作原子性代码实现阻塞队列的缺点 同步秒杀流程 public Result seckillVoucher(Long voucherId) throws InterruptedException {SeckillVoucher seckillVoucher iSeckillVoucherServi…...

项目整合logback日志打印线程id

项目打印日志能帮助我们解决很多的问题&#xff0c;提示我们出现的问题&#xff0c;通过日志我们可以准确的定位问题快速找到问题点解决问题。 <?xml version"1.0" encoding"UTF-8"?> <!-- 日志级别从低到高分为TRACE < DEBUG < INFO &l…...

WEB开发: 丢掉包袱,拥抱ASP.NET CORE!

今天的 Web 开发可以说进入了一个全新的时代&#xff0c;前后端分离、云原生、微服务等等一系列现代技术架构应运而生。在这个背景下&#xff0c;作为开发者&#xff0c;你一定希望找到一个高效、灵活、易于扩展且具有良好性能的框架。那么&#xff0c;ASP.NET Core 显然是一个…...

爬虫专栏第一篇:深入探索爬虫世界:基础原理、类型特点与规范要点全解析

本专栏会对爬虫进行从0开始的讲解&#xff0c;每一步都十分的细致&#xff0c;如果你感兴趣希望多多点赞收藏关注支持 简介&#xff1a;文章对爬虫展开多方面剖析。起始于爬虫的基本概念&#xff0c;即依特定规则在网络抓取信息的程序或脚本&#xff0c;在搜索引擎信息提取上作…...

SpringBoot3 + Vue3 由浅入深的交互 基础交互教学2

目录 一、这篇文章是基础交互教学系列的续作 二、发送请求时&#xff0c;携带发送的数据json格式的参数&#xff1a;data 三、携带token请求头&#xff0c;进行JWT校验 四、实现throw抛出异常&#xff0c;并交互显示在前端的界面 一、这篇文章是基础交互教学系列的续作 大…...

PID模糊控制算法(附MATLAB仿真程序)

一、基本原理 PID模糊控制算法是一种将传统PID控制与模糊逻辑相结合的控制策略。它利用模糊逻辑处理不确定性和非线性问题的能力&#xff0c;以提高控制系统的性能。以下是PID模糊控制算法的基本原理&#xff1a; 1.1. **误差和误差变化率的计算**&#xff1a; - 首先&…...

云轴科技ZStack助力 “上科大智慧校园信创云平台”入选上海市2024年优秀信创解决方案

近日&#xff0c;为激发创新活⼒&#xff0c;促进信创⾏业⾼质量发展&#xff0c;由上海市经济信息化委会同上海市委网信办、上海市密码管理局、上海市国资委等主办的“2024年上海市优秀信创解决方案”征集遴选活动圆满落幕。云轴科技ZStack支持的“上科大智慧校园信创云平台”…...

分布式集群下如何做到唯一序列号

优质博文&#xff1a;IT-BLOG-CN 分布式架构下&#xff0c;生成唯一序列号是设计系统常常会遇到的一个问题。例如&#xff0c;数据库使用分库分表的时候&#xff0c;当分成若干个sharding表后&#xff0c;如何能够快速拿到一个唯一序列号&#xff0c;是经常遇到的问题。实现思…...

Linux vi/vim

Linux vi/vim 所有的 Unix Like 系统都会内建 vi 文书编辑器&#xff0c;其他的文书编辑器则不一定会存在。 但是目前我们使用比较多的是 vim 编辑器。 vim 具有程序编辑的能力&#xff0c;可以主动的以字体颜色辨别语法的正确性&#xff0c;方便程序设计。 什么是 vim&…...