客户端与服务端之间的通信连接
目录
那什么是Socket?
什么是ServerSocket?
代码展示:
代码解析:
补充:
输入流(InputStream):
输出流(OutputStream):
`BufferedReader` 是如何提高读取效率的?
`BufferedWritter` 是如何提高读取效率的?
在Java中实现客户端与服务器端之间的连接通常可以通过Socket和ServerSocket类来实现。
那什么是Socket?
- Socket(套接字)是在网络编程中使用的一种抽象概念,用于建立不同计算机之间的通信连接。Socket允许不同计算机上的应用程序通过网络进行数据交换。
- 在Java编程中,Socket类是对套接字的抽象表示,提供了用于网络通信的接口。通过Socket类,可以实现客户端和服务器之间的通信,包括数据的发送和接收。
- 在一个通信过程中,客户端和服务器端各自创建一个Socket对象,并通过这个Socket对象来进行通信。客户端通过Socket连接服务器端的地址和端口号,然后可以通过Socket对象发送数据到服务器端;服务器端接收到客户端的请求后,也会创建一个新的Socket对象与客户端建立连接,从而进行数据交换。
- Socket对象在使用完毕后需要进行关闭操作,以释放资源和终止通信连接。在Java编程中,通常会在try-with-resources语句中使用Socket对象,以确保在通信结束时Socket对象能够被正确关闭。
- 总的来说,Socket类在网络编程中扮演着重要的角色,它提供了一种简单而有效的方式来实现计算机之间的通信和数据交换。
什么是ServerSocket?
- ServerSocket是Java编程语言中的一个类,用于在服务器端创建一个服务器套接字,监听客户端的连接请求。通过ServerSocket,服务器端可以接收来自客户端的连接,并与客户端建立通信连接。
- ServerSocket类提供了创建服务器套接字、监听端口、接受客户端连接请求等功能。通过ServerSocket的accept()方法,服务器端可以等待客户端的连接请求,并一旦有客户端请求连接,accept()方法将返回一个Socket对象,服务器端可以通过这个Socket对象与客户端进行通信。
- 在一个典型的网络应用程序中,服务器端通常会使用ServerSocket来初始化并监听一个特定的端口,等待客户端连接,然后处理客户端请求并进行相应的回复。ServerSocket类被广泛应用于Java网络编程中,用于实现服务器端的监听与响应。
- 需要注意的是,ServerSocket通常用在服务器端,用于监听客户端连接请求;而连接到服务器的客户端将会使用普通的Socket对象进行通信。通过ServerSocket和Socket相互配合,可以实现服务器端与多个客户端之间的连接通信。
- 总的来说,ServerSocket是Java中用于创建服务器套接字、接收客户端连接请求的重要类,是实现基于TCP协议的服务器端网络通信的关键组件。
代码展示:
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
//【服务端】
public class AIzzServer {public static HashMap<String,String> map=new HashMap<>();static {map.put("你好", "你好呀,孙子");map.put("hi", "hello,孙子");map.put("hello", "hi,孙子");map.put("吃了吗", "没呢,孙子");map.put("很高兴认识你", "我也是哦");}public static void main(String[] args) {try(ServerSocket serverSocket=new ServerSocket(8848)){while(true) {Socket clientSocket=serverSocket.accept();String clientIp=clientSocket.getInetAddress().getHostAddress();//输入流:读取客户端发送的”问题“//输出流:发送问题的答案给客户端try(BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));BufferedWriter writer=new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()))){//读取来自客户端的”问题“String question=reader.readLine();if(question==null||question.length()==0){continue;}System.out.printf("来自客户端[%s]的问题:%s\n",clientIp,question);String answer=map.get(question);answer=answer==null?"对不起,我不知道你在说什么!":answer;//将问题的答案输出至”客户端“writer.write(answer);}}} catch (IOException e) {throw new RuntimeException(e);}}
}
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;//【客户端】
public class AIzzClient {public static void main(String[] args) {try(Scanner input=new Scanner(System.in)){//读取控制台输入的问题String question=input.nextLine();//创建Socket,输出流,输入流try(Socket clientSocket=new Socket(InetAddress.getLocalHost(),8848);BufferedReader reader=new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));BufferedWriter writer=new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));){//向服务端发送”问题“(输出至服务端)writer.write(question);writer.flush();//暂时关闭输出流clientSocket.shutdownOutput();//接收服务端返回的“答案”String ans=reader.readLine();System.out.println("来自服务端的回答:"+ans);} catch (UnknownHostException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);}}}
}
代码解析:
上述代码展示了一个基于 TCP 协议的简单人工对打程序,包括服务端 `AIzzServer` 和客户端 `AIzzClient` 两个部分。
服务端 `AIzzServer` 主要负责:
- 1. 创建一个监听端口为 `8848` 的 `ServerSocket` ,等待客户端连接。
- 2. 当有客户端连接成功时,获取客户端的 IP 地址。
- 3. 通过输入流读取客户端发送的问题,并在预先定义的 `HashMap` 中查找对应的答案。如果问题不存在于 `HashMap` 中,则返回默认的回答“对不起,我不知道你在说什么!”。
- 4. 将找到的答案通过输出流发送回客户端。
客户端 `AIzzClient` 主要负责:
- 1. 从控制台读取用户输入的问题。
- 2. 创建与本地主机 `8848` 端口的连接。
- 3. 通过输出流向服务端发送问题。
- 4. 发送完成后关闭输出流。
通过输入流接收服务端返回的答案,并打印输出。 两者通过 TCP 协议进行通信,客户端发送问题,服务端接收并处理后返回答案,形成了一个简单的交互流程。例如,当用户在客户端输入“你好”,客户端将这个问题发送给服务端,服务端从 `HashMap` 中找到对应的“你好呀,孙子”并返回给客户端,客户端接收并显示出来。
补充:
输入流(InputStream):
输入流用于从数据源读取数据到程序中。数据源可以是文件、网络连接、内存缓冲区等。
它提供了一系列方法,允许程序按顺序读取数据的一部分或全部。常见的输入流操作包括读取一个字节、读取一组字节、读取一个字符、读取一行文本等。
例如,FileInputStream
可以从文件中读取字节数据,BufferedReader
可以更高效地从字符输入流中读取文本行。
输出流(OutputStream):
输出流则用于将程序中的数据写入到数据目的地。目的地同样可以是文件、网络连接、内存缓冲区等。
输出流提供了方法来将数据按顺序写入,例如写入一个字节、写入一组字节、写入一个字符等。
比如,FileOutputStream
用于向文件中写入字节数据,PrintWriter
常用于向输出流中写入格式化的文本。
总的来说,输入流和输出流是 Java 中用于实现数据在程序与外部数据源或目的地之间传输的重要机制。通过合理使用不同类型的输入流和输出流,可以方便地处理各种数据的读取和写入操作。
`BufferedReader` 是如何提高读取效率的?
`BufferedReader` 通过内部的缓冲区来提高读取效率。 当使用普通的输入流(如 `FileReader` )读取数据时,每次读取操作可能都会导致与底层数据源(例如文件)的直接交互,这可能会带来较高的系统开销,特别是在频繁读取小量数据的情况下。
而 `BufferedReader` 在其内部维护了一个缓冲区(通常是一个字节数组)。当调用读取方法时,它首先尝试从缓冲区中获取数据。如果缓冲区中有足够的数据,就直接返回,避免了频繁地与底层数据源进行交互。 当缓冲区中的数据不足时,`BufferedReader` 会一次性从底层输入流中读取较大块的数据填充缓冲区,而不是每次只读取一个字节或几个字节。
例如,如果缓冲区大小设置为 8192 字节,那么 `BufferedReader` 可能会一次性从底层输入流读取 8192 字节的数据放入缓冲区,后续的读取操作只要从缓冲区获取即可,大大减少了与底层输入流交互的次数,从而显著提高了读取效率。 这种缓冲机制特别适用于按行读取文本文件的情况,因为按行读取时,可能需要多次读取少量的数据,`BufferedReader` 的缓冲作用能有效地优化这种操作。
`BufferedWritter` 是如何提高读取效率的?
`BufferedWriter` 主要通过内部的缓冲区来提高写入效率。 当使用普通的字符输出流(如 `FileWriter`)进行写入操作时,每次写入一个字符或一小段数据,都可能会引发与底层输出目的地(例如文件)的实际交互,这会带来较多的系统开销。
而 `BufferedWriter` 在其内部维护了一个缓冲区(通常是一个字符数组)。当调用写入方法(如 `write`)时,数据并不是直接写入到目的地,而是先被存储到缓冲区中。 缓冲区有一定的大小,当缓冲区被填满或者手动调用 `flush` 方法时,`BufferedWriter` 会一次性地将缓冲区中的数据写入到底层输出流中。这样就减少了与底层输出目的地交互的次数,从而显著提高了写入效率。
例如,在向文件写入大量数据时,如果不使用 `BufferedWriter`,可能需要频繁地进行磁盘 I/O 操作,而使用 `BufferedWriter` 后,只需在缓冲区满或主动刷新时才进行实际的磁盘写入,大大降低了磁盘 I/O 的次数。 一般情况下,使用默认大小的缓冲区即可满足大多数需求。但如果明确知道写入数据的特征,也可以在创建 `BufferedWriter` 对象时指定缓冲区的大小,
相关文章:
客户端与服务端之间的通信连接
目录 那什么是Socket? 什么是ServerSocket? 代码展示: 代码解析: 补充: 输入流(InputStream): 输出流(OutputStream): BufferedReader 是如何提高读取效率的&a…...
Font Awesome 图表图标
Font Awesome 图表图标 Font Awesome 是一个广泛使用的图标库,它提供了大量的图标,可以轻松地用于网页设计和开发中。在本文中,我们将重点介绍 Font Awesome 中的图表图标,探讨它们的特点、使用方法,并展示一些实际的…...

React Native 自定义 Hook 获取组件位置和大小
在 React Native 中自定义 Hook useLayout 获取 View、Pressable 等组件的位置和大小的信息 import {useState, useCallback} from react import {LayoutChangeEvent, LayoutRectangle} from react-nativeexport function useLayout() {const [layout, setLayout] useState&l…...

如何在SpringCloud中使用Kafka Streams实现实时数据处理
使用Kafka Streams在Spring Cloud中实现实时数据处理可以帮助我们构建可扩展、高性能的实时数据处理应用。Kafka Streams是一个基于Kafka的流处理库,它可以用来处理流式数据,进行流式计算和转换操作。 下面将介绍如何在Spring Cloud中使用Kafka Streams实…...

InterSystems IRIS使用python pyodbc连接 windows环境,odbc驱动安装,DSN配置,数据源配置
一、创建的数据库和数据 SELECT 1SELECT $ZVERSIONCREATE TABLE MyApp.Person ( ID INT PRIMARY KEY, Name VARCHAR(100) NOT NULL, Age INT, Gender CHAR(1) );CREATE TABLE MyApp.Person2 ( ID INT PRIMARY KEY, Name VARCHAR(100) NOT NULL, Age INT, Gender CHA…...

JVM:运行时数据区
文章目录 一、总览二、程序计数器1、介绍2、程序计数器在运行中会出现内存溢出吗? 三、栈1、介绍2、栈帧的组成部分(1)局部变量表(2)操作数栈(3)帧数据(3)栈内存溢出&…...
spring-boot2.x整合Kafka步骤
1.pom依赖添加 <properties><java.version>1.8</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</ma…...

信创学习笔记(四),信创之数据库DB思维导图
创作不易 只因热爱!! 热衷分享,一起成长! “你的鼓励就是我努力付出的动力” 一. 信创学习回顾 1.信创内容 信创内容思维导图 2.信创之CPU芯片架构 信创之CPU芯片架构思维导图 3.信创之操作系统OS 信创之操作系统OS思维导图 二. 信创之国产数据库DB思维导图 …...
SCP 使用教程
SCP(Secure Copy Protocol)是一种通过加密的方式在本地主机和远程主机之间安全地传输文件的协议。它是基于SSH协议的扩展,允许用户在不同主机之间进行文件复制和传输,是Linux和Unix系统中常用的工具之一。本教程将详细介绍SCP的基…...

python自动化之用flask校验接口token(把token作为参数)
用到的库:flask 实现效果: 写一个接口,需要token正确才能登录 代码: # 导包 from flask import Flask,request,jsonify,json # 创建一个服务 appFlask(__name__) # post请求,路径:/query app.route(/query, met…...

旗晟巡检机器人的应用场景有哪些?
巡检机器人作为现代科技的杰出成果,已广泛应用于各个关键场景。从危险的工业现场到至关重要的基础设施,它们的身影无处不在。它们以精准、高效、不知疲倦的特性,担当起保障生产、守护安全的重任,为行业发展注入新的活力。那么&…...

vue2迁移到vue3注意点
vue2迁移到vue3注意点 1、插槽的修改 使用 #default , 以及加上template 模板 2、 类型的定义,以及路由,vue相关资源(ref, reactive,watch)的引入等 3、类装饰器 1)vue-class-component是vue官方库,作…...

使用windows批量解压和布局ImageNet ISLVRC2012数据集
使用的系统是windows,找到的解压命令很多都linux系统中的,为了能在windows系统下使用,因此下载Git这个软件,在其中的Git Bash中使用以下命令,因为Git Bash集成了很多linux的命令,方便我们的使用。 ImageNe…...

css实现每个小盒子占32%,超出就换行
代码 <div class"visitors"><visitor class"item" v-for"(user,index) in userArr" :key"user.id" :user"user" :index"index"></visitor></div><style lang"scss" scoped&…...

C++的链接指示extern “C“
目录 链接指示extern "C"A.What(概念)B.Why(extern "C"的作用)C.How (如何使用链接指示extern "C") 链接指示extern “C” A.What(概念) extern&quo…...
私域运营 组织架构
**揭秘私域社群运营的神秘面纱:角色与职能一网打尽!** 在私域社群运营的大舞台上,每个角色都扮演着不可或缺的重要角色。今天,就让我们一起揭开这个神秘世界的面纱,看看这些角色们是如何协同作战,共同创造…...
Netty HTTP
Netty 是一个高性能的异步事件驱动的网络应用程序框架,支持快速开发可维护的高性能协议服务器和客户端。它广泛应用于开发网络应用程序,如服务器和客户端协议的实现。Netty 提供了对多种传输类型的抽象,如 TCP/IP 和 UDP/IP 等,使…...

什么是边缘计算技术和边缘计算平台?
随着物联网、5G技术和人工智能的不断发展,数据的规模和种类也在快速增加。在这种背景下,传统的云计算模式面临着一些问题,例如延迟高、网络拥塞等,这些问题限制了数据的处理速度和效率,降低了用户的使用体验。为了解决…...
自然语言处理(NLP)——法国工程师IMT联盟 期末考试题
1. 问题1 (法语)En langue arabe lcrasante majorit des mots sont forms par des combinaisons de racines et de schmes. Dans ce mcanisme... (英语)In Arabic language the vast majority(十之八九) of…...

Linux内核编译安装 - Deepin,Debian系
为什么要自己编译内核 优点 定制化:你可以根据自己的硬件和需求配置内核,去掉不必要的模块,优化性能。性能优化:移除不需要的驱动程序和特性,减小内核体积,提高系统性能。最新特性和修复:获取…...

7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...

uniapp手机号一键登录保姆级教程(包含前端和后端)
目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号(第三种)后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...