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

TCP协议网络编程 回显服务器,客户端实现

        回显服务器表示客户端传来的请求是什么,服务器就回应什么,客户端不用对传来的数据进行处理,主要是为了熟悉TCP协议提供的API的使用

对于代码的解释全作为注释写在了代码上,推荐复制到编程软件中查看

UDP协议实现回显服务器可以看UDP数据报网络编程(实现简单的回显服务器,客户端)

其中涉及到的线程池的内容可以看通过标准库创建线程池

idea开启多个客户端的方法可以看idea如何开启多个客户端(一个代码开启多个客户端运行)

服务器代码

package TcpEcho;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;/*** Created with IntelliJ IDEA.* Description:* User: wuyulin* Date: 2023-08-10* Time: 16:25*/
//TCP协议 回显服务器(客户端传来的请求是什么,服务器就回应什么)
//TCP协议网络编程两个最主要的类是ServerSocket和Socket
public class TcpEchoServer {//线程池对象ExecutorService executorService= null;//ServerSocket类内置了一个队列,在内核中客户端和服务器尝试建立连接,连接建立完了以后得到的连接对象就存入了队列中//客户端和服务器尝试建立连接,进行一系列的数据交互称为“握手”,这个过程建立完了以后,连接就建立好了private ServerSocket serverSocket=null;//在构造方法中实例化serverSocket对象,port参数表示在创建服务器时要指定服务器的ip地址TcpEchoServer(int port) throws IOException {serverSocket=new ServerSocket(port);executorService=Executors.newCachedThreadPool();    //实例化一个线程数目动态变化的线程池}public void start() throws IOException {//写日志,方便观察当前运行状态System.out.println("服务器启动");//服务器需要不停的去接收客户端传来的请求并做出回应,所以需要一个死循环while (true){//TCP是有连接的,需要处理服务器与客户端之间的连接,而UDP是无连接的,不需要处理//处理服务器与客户端之间的连接//通过调用accept方法,取出serverSocket对象内置的队列中的连接对象(Socket对象)//当队列中没有Socket连接对象时,就会在accept方法这里进入阻塞等待,直到取得连接对象为止Socket socket=serverSocket.accept();//对获得的服务器与客户端之间的连接对象进行处理//采用当前的编写方式会发现当有多个客户端来连接服务器并发出请求时,服务器不能同时处理//因为在handleConnection方法中会一直循环处理客户端发出的请求//而当前编写方式要等handleConnection方法执行完毕才能去取出下一个连接对象,才能处理下一个客户端发出的请求// handleConnection(socket);//解决办法:用主线程去调用accept方法取出连接对象,每取出一个连接对象就创建一个线程去处理连接对象对应的客户端发出的请求//但下面这个创建线程来处理socket连接对象的代码也注释掉了,这是因为要是有很多客户端来对服务器发出请求,就会涉及到大量//线程的创建和销毁,这是很消耗资源的,所以应该采用线程池来处理socket连接对象
//            Thread t=new Thread(()->{
//                try {
//                    handleConnection(socket);
//                } catch (IOException e) {
//                    throw new RuntimeException(e);
//                }
//            });
//
//            t.start();//在该服务器类的成员属性中添加上线程池//将处理连接对象的任务通过submit添加到线程池的阻塞队列中(线程池中的线程会将添加到阻塞队列中的任务进行处理)executorService.submit(new Runnable() {@Overridepublic void run() {try {handleConnection(socket);} catch (IOException e) {throw new RuntimeException(e);}}});}}//处理客户端和服务器之间的连接,并且完成数据的接收,处理,回应public void handleConnection(Socket socket) throws IOException {System.out.printf("客户端上线 %s %d\n",socket.getInetAddress().toString(),socket.getPort());//由于TCP协议的网络编程,进行数据传输的基本单位是字节,所以需要inputstream和outputstream类型的对象来处理字节流的数据//socket网络连接对象可以直接实例化InputStream和OutputStream对象来对网络要传输的字节数据进行处理//采用try(){}的结构,在()中实例化inputStream和outputStream对象,可以在{}中的程序执行结束了以后自动关闭这两个对象(防止内存泄漏)try(InputStream inputStream=socket.getInputStream();OutputStream outputStream=socket.getOutputStream()){//处理客户端传来的请求//客户端传来的请求可能不止一个,所以需要一直死循环去一直读取客户端传来的请求while (true){//InputStream直接使用不是很方便,包装一层Scanner使用Scanner scanner=new Scanner(inputStream);//当没有读取到请求了(客户端传来的请求读取完了)就跳出循环,结束方法,去拿下一个网络连接对象进行处理//当客户端还没有传入请求时就会进入阻塞等待,直到客户端传入请求或客户端下线才恢复if(!scanner.hasNext()){//只有当客户端下线才会执行这段代码System.out.printf("%s %d客户端下线",socket.getInetAddress().toString(),socket.getPort());break;}//客户端中还有请求,读取客服端的请求到request字符串中//这里默认了客户端传来的请求是字符串,按照字符串的形式来处理请求String request=scanner.next();//对客户端传来的请求进行处理并作出响应String response=handle(request);//将响应传递给客户端//直接使用outputStream比较麻烦,包装一层PrintWriter进行使用PrintWriter printWriter=new PrintWriter(outputStream);//要调用println方法将回应传递给客户端才行,因为println方法在传递了一个回应后会换行,而在客户端中就刚好可以用next方法读取//(next方法不会读取空白符,而换行属于空白符)printWriter.println(request);//由于IO操作很消耗资源,所以在调用println方法向客户端发送数据时会先将数据放到一个内存缓冲区中,等到有一定的内容再一起发送//所以为了保证回应被及时的发到客户端,就要对内存缓冲区进行刷新printWriter.flush();//写日志,方便观察当前运行状态System.out.printf("[%s,%d] request:%s response:%s\n",socket.getInetAddress().toString(),socket.getPort(),request,response);}} catch (IOException e) {throw new RuntimeException(e);}finally {  //Socket连接对象会被不停的从serverSocket对象中取出,所以在使用完毕Socket连接对象以后应该调用close方法关闭,否则会出现内存泄漏socket.close();}}//对客户端传来的请求进行处理public String handle(String request){return request;}public static void main(String[] args) throws IOException {TcpEchoServer tcpEchoServer=new TcpEchoServer(1010);tcpEchoServer.start();}
}

客户端代码

package TcpEcho;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Scanner;/*** Created with IntelliJ IDEA.* Description:* User: wuyulin* Date: 2023-08-10* Time: 19:26*/
//TCP回显客户端
public class TcpEchoClient {//客户端需要实例化一个连接对象Socket来实现客户端与服务器之间的数据交互Socket socket=null;//在实例化连接对象Socket时需要服务器的ip地址和端口号TcpEchoClient(String serverIp,int serverPort) throws IOException {socket=new Socket(serverIp,serverPort);}public void start(){//写日志,方便观察当前运行状态System.out.println("客户端启动");//TCP协议进行网络编程传递数据的基本单位是字节,所以需要用到InputStream和OutputStream的对象来进行数据的传输//通过连接对象即可实例化InputStream和OutputStream的对象try(InputStream inputStream=socket.getInputStream();OutputStream outputStream=socket.getOutputStream();){//客户端需要不停的读取客户输入的请求,所以要用循环while (true){Scanner scanner=new Scanner(System.in);//读取用户的请求System.out.println("->");String request=scanner.next();//将用户的请求发送给服务器//直接使用outputStream不方便,包装一层PrintWriter使用PrintWriter printWriter=new PrintWriter(outputStream);printWriter.println(request);//由于IO操作很消耗资源,所以在调用println方法向客户端发送数据时会先将数据放到一个内存缓冲区中,等到有一定的内容再一起发送//所以为了保证请求被及时的发到服务器,就要对内存缓冲区进行刷新printWriter.flush();//接收服务器处理后的回应//直接使用inputStream不方便,包装一层Scanner使用Scanner inputScanner=new Scanner(inputStream);String response=inputScanner.next();//将回应打印到控制台System.out.println(response);}} catch (IOException e) {throw new RuntimeException(e);}}public static void main(String[] args) throws IOException {TcpEchoClient tcpEchoClient=new TcpEchoClient("127.0.0.1",1010);tcpEchoClient.start();}
}

相关文章:

TCP协议网络编程 回显服务器,客户端实现

回显服务器表示客户端传来的请求是什么,服务器就回应什么,客户端不用对传来的数据进行处理,主要是为了熟悉TCP协议提供的API的使用 对于代码的解释全作为注释写在了代码上,推荐复制到编程软件中查看 UDP协议实现回显服务器可以看…...

3.4 Spring MVC注解

注解名称 注解说明 RequestMapping 用来处理请求地址映射的注解,可以在接口、类和方法上使用 value属性 表示请求地址,与path属性一致 method属性 表示接收HTTP请求方法,默认接收所有请求方法,请求包括GET、POST、PUT、DEL…...

OpenCV实例(八)车牌字符识别技术(三)汉字识别

车牌字符识别技术(三)汉字识别 1.代码实例2.遇到问题3.汉字识别代码实例 相较于数字和英文字符的识别,汽车牌照中的汉字字符识别的难度更大,主要原因有以下4个方面: (1)字符笔画因切分误差导致非笔画或笔画流失。 (2…...

运维监控学习笔记2

硬件监控: 1)使用IPMI 2)机房巡检 路由器和交换机: 使用SNMP(简单网络管理协议)进行监控。 Linux 安装snmp: yum install -y net-snmp net-snmp-utils 说明:net-snmp是安装在snm…...

【深度学习】遗传算法[选择、交叉、变异、初始化种群、迭代优化、几何规划排序选择、线性交叉、非均匀变异]

目录 一、遗传算法二、遗传算法概述2.1 选择2.2 交叉2.3 变异 三、遗传算法的基本步骤3.1 编码3.2 初始群体的生成3.3 适应度评估3.4 选择3.5 交叉3.6 变异3.7 总结 四、遗传算法工具箱4.1 initializega4.2 ga4.3 normGeomSelect4.4 arithXover4.5 nonUnifMutation 五、遗传算法…...

【小吉带你学Git】讲解GitHub操作,码云操作,GitLab操作

🎊专栏【Git】 🍔喜欢的诗句:更喜岷山千里雪 三军过后尽开颜。 🎆音乐分享【如愿】 🌺欢迎并且感谢大家指出小吉的问题🥰 文章目录 🍔GitHub操作⭐安装GitHub插件⭐在idea中设置GitHub账号&…...

nginx基础

nginx 具体就是一个轻量级以及高性能的web服务软件。 nginx特点 1、稳定性高。(但不如apache) 2、系统资源消耗比较低。(处理http请求的并发能力较高,单台处理器可以处理3w-5w的并发请求) 注:一般在企…...

【Windows API】获取卷标、卷名

1、卷->卷标 使用FindFirstVolume()和FindNextVolume()函数体系,枚举系统所有卷(Volume)的例子,然后获取卷标、卷类型。这个方式可以枚举出没有驱动器号(卷标)的卷。 int TestMode1() {HANDLE hVolume…...

通过MATLAB自动产生Hamming编译码的verilog实现,包含testbench

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 1. 原理 1.1 编码规则 1.2 错误检测和纠正 2. 实现过程 2.1 编码过程 2.2 解码过程 3. 应用领域 3.1 数字通信 3.2 存储系统 3.3 ECC内存 3.4 数据传输 5.算法完整程序工程 1.算法…...

swager web服务无法显示问题

如果指定了扫描其他包 那么web文件夹里面的就扫描不到 需要加上扫描扫描web的 ,默认什么也没有就会扫描web文件夹 但是其他模块的扫描不到 指定了扫描其他模块就需要再次指定扫描该web文件夹...

代码随想录训练营day18 二叉树

106. 从中序与后序遍历序列构造二叉树 给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。 //左根右 左右根/* 第一步:如果数组大小为零的…...

图像的平移变换之c++实现(qt + 不调包)

1.基本原理 设dx为水平偏移量&#xff0c;dy为垂直偏移量&#xff0c;则平移变换的坐标映射关系为下公式&#xff0c;图像平移一般有两种方式。 1.不改变图像大小的平移&#xff08;一旦平移&#xff0c;相应内容被截掉&#xff09; 1&#xff09;当dx > width、dx < -wi…...

云原生K8S------Yaml文件详解

目录 一&#xff1a;K8S支持的文件格式 1&#xff0c;yaml和json的主要区别 2&#xff0c;YAML语言格式 二&#xff1a;yuml 1、查看 api 资源版本标签 2、写一个yaml文件demo 3、创建service服务对外提供访问并测试 4、详解k8s中的port 三&#xff1a;文件生成 1、kubec…...

测试开发环境安装

安装python运行环境 下载地址&#xff1a;链接 http://python.p2hp.com/downloads/windows/index.html 选择合适自己的版&#xff0c;我下载的3.8.10的进行安装 安装码编辑器Pychrom 下载地址&#xff1a;链接 https://www.jetbrains.com/pycharm/ 拉到最下面可以下载社区版…...

微信小程序如何引入Iconfont

在小程序中引入 Iconfont 可以通过以下步骤进行操作&#xff1a; 打开 Iconfont 网站&#xff08;https://www.iconfont.cn/&#xff09;并登录账号&#xff0c;创建一个项目并添加所需的图标到项目中。 在项目中选中需要使用的图标&#xff0c;点击右上角的 “下载代码” 按钮…...

php使用get和post传递数据出现414 Request-URI Too Large的解决方案

递数据出现414 Request-URI Too Large的解决方案 一、Request-URI Too Large的原因二、GET与POST三、项目分析1.读取源数据2.将读取的到数据&#xff0c;进行传递3.ajax获取传递的数据并传递到后台4.传递数据5.解决方案 一、Request-URI Too Large的原因 “Request-URI Too La…...

复现大华智慧园区综合管理平台SQL注入漏洞

目录 一、漏洞描述 二、影响版本 三、资产测绘 四、漏洞复现 一、漏洞描述 大华智慧园区综合管理平台是一个集智能化、信息化、网络化、安全化为一体的智慧园区管理平台,旨在为园区提供一站式解决方案,包括安防、能源管理、环境监测、人员管理、停车管理等多个方面。大华…...

【uniapp】uniapp设置安全区域:

文章目录 一、效果图:二、实现代码: 一、效果图: 二、实现代码: {"path": "pages/index/index","style": {"navigationStyle": "custom","navigationBarTextStyle": "white","navigationBarTitle…...

Grafana技术文档--基本安装-docker安装并挂载数据卷-《十分钟搭建》-附带监控服务器

阿丹&#xff1a; Prometheus技术文档--基本安装-docker安装并挂载数据卷-《十分钟搭建》_一单成的博客-CSDN博客 在正确安装了Prometheus之后开始使用并安装Grafana作为Prometheus的仪表盘。 一、拉取镜像 搜索可拉取版本 docker search Grafana拉取镜像 docker pull gra…...

24大连交通大学软件工程813题库

1&#xff0e;下面错误的说法是( )。 A&#xff0e; 每个数据流必须用名词或名词短语命名 B&#xff0e;每个加工必须有名字&#xff0c;通常是动词短语 c&#xff0e;每个数据存储必须用名词或名词短语 D&#xff0e;每个数据源点或终点必须有名字 答案:C 2&#xff0e;下…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)

推荐 github 项目:GeminiImageApp(图片生成方向&#xff0c;可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能

1. 开发环境准备 ​​安装DevEco Studio 3.1​​&#xff1a; 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK ​​项目配置​​&#xff1a; // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...

【Kafka】Kafka从入门到实战:构建高吞吐量分布式消息系统

Kafka从入门到实战:构建高吞吐量分布式消息系统 一、Kafka概述 Apache Kafka是一个分布式流处理平台,最初由LinkedIn开发,后成为Apache顶级项目。它被设计用于高吞吐量、低延迟的消息处理,能够处理来自多个生产者的海量数据,并将这些数据实时传递给消费者。 Kafka核心特…...

2025年低延迟业务DDoS防护全攻略:高可用架构与实战方案

一、延迟敏感行业面临的DDoS攻击新挑战 2025年&#xff0c;金融交易、实时竞技游戏、工业物联网等低延迟业务成为DDoS攻击的首要目标。攻击呈现三大特征&#xff1a; AI驱动的自适应攻击&#xff1a;攻击流量模拟真实用户行为&#xff0c;差异率低至0.5%&#xff0c;传统规则引…...

【Ftrace 专栏】Ftrace 参考博文

ftrace、perf、bcc、bpftrace、ply、simple_perf的使用Ftrace 基本用法Linux 利用 ftrace 分析内核调用如何利用ftrace精确跟踪特定进程调度信息使用 ftrace 进行追踪延迟Linux-培训笔记-ftracehttps://www.kernel.org/doc/html/v4.18/trace/events.htmlhttps://blog.csdn.net/…...

理想汽车5月交付40856辆,同比增长16.7%

6月1日&#xff0c;理想汽车官方宣布&#xff0c;5月交付新车40856辆&#xff0c;同比增长16.7%。截至2025年5月31日&#xff0c;理想汽车历史累计交付量为1301531辆。 官方表示&#xff0c;理想L系列智能焕新版在5月正式发布&#xff0c;全系产品力有显著的提升&#xff0c;每…...