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为水平偏移量,dy为垂直偏移量,则平移变换的坐标映射关系为下公式,图像平移一般有两种方式。 1.不改变图像大小的平移(一旦平移,相应内容被截掉) 1)当dx > width、dx < -wi…...

云原生K8S------Yaml文件详解
目录 一:K8S支持的文件格式 1,yaml和json的主要区别 2,YAML语言格式 二:yuml 1、查看 api 资源版本标签 2、写一个yaml文件demo 3、创建service服务对外提供访问并测试 4、详解k8s中的port 三:文件生成 1、kubec…...
测试开发环境安装
安装python运行环境 下载地址:链接 http://python.p2hp.com/downloads/windows/index.html 选择合适自己的版,我下载的3.8.10的进行安装 安装码编辑器Pychrom 下载地址:链接 https://www.jetbrains.com/pycharm/ 拉到最下面可以下载社区版…...

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

php使用get和post传递数据出现414 Request-URI Too Large的解决方案
递数据出现414 Request-URI Too Large的解决方案 一、Request-URI Too Large的原因二、GET与POST三、项目分析1.读取源数据2.将读取的到数据,进行传递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安装并挂载数据卷-《十分钟搭建》-附带监控服务器
阿丹: Prometheus技术文档--基本安装-docker安装并挂载数据卷-《十分钟搭建》_一单成的博客-CSDN博客 在正确安装了Prometheus之后开始使用并安装Grafana作为Prometheus的仪表盘。 一、拉取镜像 搜索可拉取版本 docker search Grafana拉取镜像 docker pull gra…...
24大连交通大学软件工程813题库
1.下面错误的说法是( )。 A. 每个数据流必须用名词或名词短语命名 B.每个加工必须有名字,通常是动词短语 c.每个数据存储必须用名词或名词短语 D.每个数据源点或终点必须有名字 答案:C 2.下…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...

黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 
关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...

华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)
在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...
Caliper 负载(Workload)详细解析
Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...