客户端与服务端之间的通信连接

目录

那什么是Socket?

什么是ServerSocket?

代码展示:

代码解析:

补充:

输入流(InputStream):

输出流(OutputStream):

`BufferedReader` 是如何提高读取效率的?

`BufferedWritter` 是如何提高读取效率的?


在Java中实现客户端与服务器端之间的连接通常可以通过SocketServerSocket类来实现。

那什么是Socket?

  1. Socket(套接字)是在网络编程中使用的一种抽象概念,用于建立不同计算机之间的通信连接。Socket允许不同计算机上的应用程序通过网络进行数据交换。
  2. 在Java编程中,Socket类是对套接字的抽象表示,提供了用于网络通信的接口。通过Socket类,可以实现客户端和服务器之间的通信,包括数据的发送和接收。
  3. 在一个通信过程中,客户端和服务器端各自创建一个Socket对象,并通过这个Socket对象来进行通信。客户端通过Socket连接服务器端的地址和端口号,然后可以通过Socket对象发送数据到服务器端;服务器端接收到客户端的请求后,也会创建一个新的Socket对象与客户端建立连接,从而进行数据交换。
  4. Socket对象在使用完毕后需要进行关闭操作,以释放资源和终止通信连接。在Java编程中,通常会在try-with-resources语句中使用Socket对象,以确保在通信结束时Socket对象能够被正确关闭。
  5. 总的来说,Socket类在网络编程中扮演着重要的角色,它提供了一种简单而有效的方式来实现计算机之间的通信和数据交换。
     

什么是ServerSocket?

  1. ServerSocket是Java编程语言中的一个类,用于在服务器端创建一个服务器套接字,监听客户端的连接请求。通过ServerSocket,服务器端可以接收来自客户端的连接,并与客户端建立通信连接。
  2. ServerSocket类提供了创建服务器套接字、监听端口、接受客户端连接请求等功能。通过ServerSocket的accept()方法,服务器端可以等待客户端的连接请求,并一旦有客户端请求连接,accept()方法将返回一个Socket对象,服务器端可以通过这个Socket对象与客户端进行通信。
  3. 在一个典型的网络应用程序中,服务器端通常会使用ServerSocket来初始化并监听一个特定的端口,等待客户端连接,然后处理客户端请求并进行相应的回复。ServerSocket类被广泛应用于Java网络编程中,用于实现服务器端的监听与响应。
  4. 需要注意的是,ServerSocket通常用在服务器端,用于监听客户端连接请求;而连接到服务器的客户端将会使用普通的Socket对象进行通信。通过ServerSocket和Socket相互配合,可以实现服务器端与多个客户端之间的连接通信。
  5. 总的来说,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` 对象时指定缓冲区的大小,

    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/45583.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

K8s集群初始化遇到的问题

kubectl describe pod coredns-545d6fc579-s9g5s -n kube-system 找到原因1&#xff1a;CoreDNS Pod 处于 Pending 状态的原因是集群中的节点都带有 node.kubernetes.io/not-ready 污点 journalctl -u kubelet -f 14:57:59.178592 3553 remote_image.go:114] "PullIma…

《简历宝典》12 - 简历中“项目经历”,内功学习 - 下篇

这一小节呢&#xff0c;我们继续说简历中 “项目经历” 的一些内功心法。因为项目经历比较核心&#xff0c;所以说完了&#xff0c;内功呢&#xff0c;我们会着重说一下 实战部分。 目录 1 所用技术的考虑 2 自我成长的突出 3 综合使用STAR法则 4 小节 1 所用技术的考虑 …

如何评估AI模型:评估指标的分类、方法及案例解析

如何评估AI模型&#xff1a;评估指标的分类、方法及案例解析 引言第一部分&#xff1a;评估指标的分类第二部分&#xff1a;评估指标的数学基础第三部分&#xff1a;评估指标的选择与应用第四部分&#xff1a;评估指标的局限性第五部分&#xff1a;案例研究第六部分&#xff1a…

pear-admin-fast项目修改为集成PostgreSQL启动

全局搜索代码中的sysdate()&#xff0c;修改为now() 【前者是mysql特有的&#xff0c;后者是postgre特有的】修改application-dev.yml中的数据库url使用DBeaver把mysql中的数据库表导出csv&#xff0c;再从postgre中导入csv脚本转换后出现了bpchar(xx)类型&#xff0c;那么一定…

用友U8存货分类按层级取数SQL语句

SELECT cInvCCode 分类编码, cInvCName 分类名称, iInvCGrade 分类层级, ss.bInvCEnd 是否是末级, aa.* FROM InventoryClass ss LEFT JOIN ( SELECT * FROM ( SELECT cInvCCode AS 一级分类编码, …

python数据可视化(6)——绘制散点图

课程学习来源&#xff1a;b站up&#xff1a;【蚂蚁学python】 【课程链接&#xff1a;【【数据可视化】Python数据图表可视化入门到实战】】 【课程资料链接&#xff1a;【链接】】 Python绘制散点图查看BMI与保险费的关系 散点图: 用两组数据构成多个坐标点&#xff0c;考察…

如何降低老年人患帕金森病的风险?

降低老年人患帕金森病风险的方法 避免接触有害物质&#xff1a;长期接触某些化学物质、农药或其他有害物质可能会增加患帕金森病的风险。应减少这些物质的暴露&#xff0c;例如在工作或生活中采取防护措施。 健康饮食&#xff1a;均衡饮食&#xff0c;多吃富含抗氧化剂的食物&a…

做了一个万能搜索框

最近给网页做了一个搜索框&#xff0c;现在搜索比以前更加方便了&#xff0c;下面简单介绍一下如何使用 我们进入网页版&#xff08;app.zyjj.cc&#xff09;点击右上角的搜索就可以看到这个新版的搜索框了 目前支持中文、拼音、首字母等多种搜索方式&#xff0c;大家可以随意…

【Python】Python-docx使用实例 科技档案封面批量生成

使用背景 根据excel表中的信息&#xff0c;按照word模板格式&#xff0c;每条信息生成一个对应的模板及文件名。 我这里的情况是将科技档案的封面格式按照案卷表的明细批量生成。 &#xff08;单位的档案软件太鸡肋了&#xff0c;没有这个功能&#xff09; 代码整篇 工程档…

【Linux】常见指令(下)

【Linux】常见指令&#xff08;下&#xff09; 通配符 *man指令cp指令echo指令cat指令&#xff08;简单介绍&#xff09;cp指令 mv指令alias指令which ctrl ccat指令linux下一切皆文件 more指令less指令head指令tail指令管道 通配符 ‘*’ 通配符’ *‘&#xff0c;是可以匹配…

4 C 语言控制流与循环结构的深入解读

目录 1 复杂表达式的计算过程 2 if-else语句 2.1 基本结构及示例 2.2 if-else if 多分支 2.3 嵌套 if-else 2.4 悬空的 else 2.5 注意事项 2.5.1 if 后面不要加分号 2.5.2 省略 else 2.5.3 省略 {} 2.5.4 注意点 3 while 循环 3.1 一般形式 3.2 流程特点 3.3 注…

Dynamic多数据源

有时候我们在项目中&#xff0c;可能会遇到需要同时使用多个数据库连接的情况&#xff0c;这个时候可以使用MyBatis-Plus的dynamic多数据源的配置。但其实MyBatis-Plus官方还提供了mybatis-mate组件&#xff0c;但是他是付费的企业组件。 官方文档&#xff1a; 多数据源支持 …

识别视频中的人数并统计出来

目的: 使用Python和pysimpleguil以及opencv写一个统计人流量的软件。要求:1 加载选定的视频 2 通过形态学特征识别人,3统计人数并且在界面上显示出来,4 保存识别出人数的信息。 步骤 1: 安装必要的库 首先,确保你已经安装了Python。然后,安装PySimpleGUI和OpenCV。你可…

数电基础 - 可编程逻辑器件

目录 ​编辑 一. 简介 二. 现场可编程逻辑阵列 三. 可编程阵列逻辑 四. 通用阵列逻辑 五. 可擦除的可编程逻辑器件 六. 复杂的可编程逻辑器件 七. 现场可编程门阵列 一. 简介 可编程逻辑器件&#xff08;Programmable Logic Device&#xff0c;PLD&#xff09;是一种用…

Gmsh用户界面

主要指出几何、网格、求解三个模块. 几何模块分为基本实体和物理组两个部分&#xff0c;主要对几何体进行操作&#xff0c;并设置物理属性 网格模块主要定义了对网格的操作和对应的算法 求解主要指出了网格求解方法 所有的界面操作都是基于这三个方法的

半导体仿真文件传输面临时间和经济成本挑战,一招就能解决

对于芯片设计企业来说&#xff0c;其面临的最大考验就是芯片设计质量和时间成本控制之间的矛盾&#xff0c;具体表现在芯片的设计、仿真验证过程存在着较大的挑战&#xff1a; 芯片设计过程包括了仿真验证这一重要的一环&#xff0c;但芯片设计企业在仿真验证这一环却面临着较…

数据结构--二叉树遍历

目录 1.介绍 &#xff08;1&#xff09;前序遍历 &#xff08;2&#xff09;定义结构体 &#xff08;3&#xff09;前序遍历实现 &#xff08;4&#xff09;中序遍历实现 &#xff08;5&#xff09;二叉树的节点个数 &#xff08;6&#xff09;二叉树树叶节点个数 &…

数仓工具—Hive语法之宏(Macro)

Hive中的宏 许多关系型数据库,如Teradata,支持宏(Macro)函数。在关系数据库管理系统(RDBMS)中,宏存储在数据字典中。用户可以共享宏,并根据需要执行它们。Hive宏与关系型数据库中的宏略有不同。在本文中,我们将检查什么是宏,它的语法,如何使用它们,以及一些宏的示…

java 字段 大于4000拆分

java 字段 大于4000拆分 public List<String> splitJsonIfNecessary(String jsonStr) {List<String> result new ArrayList<>();while (jsonStr.length() > Constant.MAX_LENGTH) {// 直接按字符数截取&#xff0c;不考虑JSON结构String part jsonStr.s…

东软医疗 踩在中国医疗科技跃迁的风口上

恐怕没有哪一家本土医疗装备企业能像东软医疗一样&#xff0c;每一段成长的升维都发生在中国医疗科技跃迁史最重要的节点上。 在工业制造领域&#xff0c;医疗装备产业由于涉及数十个学科领域&#xff0c;其技术复合程度毫不逊于今天公众所熟知的EUV光刻机&#xff0c;是一门技…