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

【JavaEE精炼宝库】 网络编程套接字——UDP业务逻辑 | TCP流套接字编程及业务逻辑实现

文章目录

  • 一、UDP业务逻辑实现
  • 二、TCP流套接字编程
    • 2.1 API 介绍:
      • 2.1.1 ServerSocket:
      • 2.1.2 Socket:
    • 2.2 Java流套接字通信模型:
    • 2.3 代码示例:
      • 2.3.1 TCP Echo Server:
      • 2.3.2 TCP Echo Client:
      • 2.3.3 TCP Echo Server优化:
    • 2.4 长短连接:
  • 三、TCP业务逻辑实现

一、UDP业务逻辑实现

在上一节:网络编程套接字(上)中我们已经初识了网络编程和利用UDP数据报套接字进行编程。为了更加熟练掌握网络编程,接下来我们会利用UDP套接字来实现一个查询英语单词的简单业务逻辑。

  • 业务目标: 编写UDP版本的字典客户端和字典服务器:

  • 业务实现逻辑: 添加业务逻辑一般都是修改服务器。因为服务器是在我们手里的,客户端不是,且请求的回响是根据服务器来完成的。因此我们只需修改服务器代码即可,客户端的代码不用修改。

  • 业务实现:

通过对比我们发现,要在服务器实现一个查询英语单词的逻辑,其实只要修改将请求生成回响的过程即可。 由于我们前面编写的UDPServer是回显服务器,所以我们可以通过继承的方式,重写process方法即可。具体代码如下:

注意:要修改成自己电脑的 IP 地址才行。

import java.io.IOException;
import java.net.SocketException;
import java.util.HashMap;
import java.util.Map;
public class UdpDicServer extends UdpEchoServer{private Map<String,String> hash = new HashMap<>();public UdpDicServer(int port) throws SocketException {super(port);hash.put("hello","你好");hash.put("dog","小狗");hash.put("cat","小猫");}@Overridepublic String process(String request) {return hash.getOrDefault(request,"该词汇未被查询到");}public static void main(String[] args) throws IOException {UdpDicServer server = new UdpDicServer(9090);server.start();}
}

实现效果如下:
在这里插入图片描述

二、TCP流套接字编程

2.1 API 介绍:

2.1.1 ServerSocket:

ServerSocket 是创建TCP服务端Socket的API。

  • ServerSocket 构造方法:
方法签名方法说明
ServerSocket(int port)创建一个服务端流套接字Socket,并绑定到指定端口。
  • ServerSocket 普通方法:
方法签名方法说明
Socket accept()开始监听指定端口(创建时绑定的端口),有客户端连接后,返回一个服务端Socket对象,并基于该Socket建立与客户端的连接,否则阻塞等待。
void close()关闭此套接字。

2.1.2 Socket:

Socket是客户端Socket,或服务端中接收到客户端建立连接(accept方法)的请求后,返回的服 务端Socket。

不管是客户端还是服务端Socket,都是双方建立连接以后,保存对端的信息,用来与对方收发数据 。

  • Socket 构造方法:
方法签名方法说明
Socket(String host, int port)创建一个客户端流套接字Socket,并与对应IP的主机上,对应端口的进程建立连接。
  • Socket 普通方法:
方法签名方法说明
InetAddress getInetAddress()返回套接字所连接的地址。
InputStream getInputStream()返回此套接字的输入流。
OutputStream getOutputStream()返回此套接字的输出流。

2.2 Java流套接字通信模型:

TCP流套接字较UDP数据报套接字就要灵活许多,通信双方建立联系后,就可以通过我们前面学过的 IO 流进行数据传输,非常方便。
在这里插入图片描述

2.3 代码示例:

2.3.1 TCP Echo Server:

首先创建 ServerSocket,接着通过 accept 方法接收Socket,建立连接后通过 IO 流进行数据交互。

代码如下:

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;public class TcpEchoServer {private ServerSocket serverSocket = null;public TcpEchoServer(int port) throws IOException {serverSocket = new ServerSocket(port);}public void start() throws IOException {System.out.println("服务器启动!");
//        单线程while(true){Socket clientSocket = serverSocket.accept();//连接后的逻辑processConnection(clientSocket);}}/*** 处理连接后的逻辑* @param clientSocket* @throws IOException*/private void processConnection(Socket clientSocket) throws IOException {//这种写法的好处是:可以优雅的 closetry (InputStream inputStream = clientSocket.getInputStream();OutputStream outputStream = clientSocket.getOutputStream()) {Scanner in = new Scanner(inputStream);while (true) {//读取完毕if (!in.hasNext()) {System.out.printf("[%s:%d]客户端下线", clientSocket.getInetAddress(), clientSocket.getPort());break;}//获取请求String request = in.next();//根据请求计算响应String response = process(request);//将响应写回给客户端PrintWriter printWriter = new PrintWriter(outputStream);printWriter.println(response);//刷新缓存区printWriter.flush();//打印日志System.out.printf("[%s:%d] req:%s resp:%s\n", clientSocket.getInetAddress(), clientSocket.getPort(), request,response);}}finally{clientSocket.close();}}//根据请求计算响应public String process(String request) {return request;}public static void main(String[] args) throws IOException {TcpEchoServer server = new TcpEchoServer(9090);server.start();}
}

2.3.2 TCP Echo Client:

创建 Socket 向 ServerSocket 发起连接请求,连接成功后,通过 IO 流进行数据交互。

代码如下:

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;public class TcpEchoClient {private Socket socket = null;public TcpEchoClient(String serverIp, int serverPort) throws IOException {socket = new Socket(serverIp, serverPort);}public void start() throws IOException {System.out.println("客户端启动!");Scanner in = new Scanner(System.in);try (InputStream inputStream = socket.getInputStream();OutputStream outputStream = socket.getOutputStream()) {while (true) {//提示输入请求System.out.print("请输入请求:");//输入请求String request = in.next();//发送给服务器获取响应PrintWriter printWriter = new PrintWriter(outputStream);printWriter.println(request);//保证数据发送出去了printWriter.flush();Scanner scanner = new Scanner(inputStream);String response = scanner.next();//打印响应System.out.println(response);}}}public static void main(String[] args) throws IOException {TcpEchoClient client = new TcpEchoClient("192.168.0.198", 9090);client.start();}
}

演示效果如下:
在这里插入图片描述

2.3.3 TCP Echo Server优化:

普通的 TCP Echo Server 存在服务器一次只能与一个客户端进行连接的问题,这显然不是我们想要的。

在这里插入图片描述

我们可以通过前面所学的多线程来解决这个问题。给每个客户端都分配一个线程。

  • 多线程优化:

由于修改的只是 start 方法,下面就只给出 start 多线程版本,大家自己替换一下即可。

public void start() throws IOException {System.out.println("服务器启动!");
//        使用多线程来解决多个客户端的情况while (true) {Socket clientSocket = serverSocket.accept();Thread thread = new Thread(()->{try {//用该方法来封装一个连接的逻辑processConnection(clientSocket);} catch (IOException e) {throw new RuntimeException(e);}});thread.start();}}

多线程的效果如下:
在这里插入图片描述

  • 线程池优化:

采用线程池的优势有:

1. 减低资源开销: 避免频繁的创建和销毁线程带来的系统资源开销。
2. 提高响应速度: 可以直接利用线程池中存在的线程,不用等待创建线程的时间。
3. 可管理性: 进行统一的分配,可以避免大量因抢占式系统资源分配带来的阻塞。

代码如下:

public void start() throws IOException {System.out.println("服务器启动!");//线程池解决多个客户端的情况ExecutorService service = Executors.newCachedThreadPool();while(true){Socket clientSocket = serverSocket.accept();service.submit(()->{try {processConnection(clientSocket);} catch (IOException e) {throw new RuntimeException(e);}});}}

线程池效果如下:
在这里插入图片描述

2.4 长短连接:

TCP发送数据时,需要先建立连接,什么时候关闭连接就决定是短连接还是长连接:

  • 短连接: 每次接收到数据并返回响应后,都关闭连接,即是短连接。也就是说,短连接只能一次收发数据。
  • 长连接: 不关闭连接,一直保持连接状态,双方不停的收发数据,即是长连接。也就是说,长连接可以多次收发数据。

对比以上长短连接,两者区别如下:

  1. 建立连接、关闭连接的耗时: 短连接每次请求、响应都需要建立连接,关闭连接,而长连接只需要第一次建立连接,之后的请求、响应都可以直接传输。相对来说建立连接,关闭连接也是要耗时的,长连接效率更高。
  2. 主动发送请求对象: 短连接一般是客户端主动向服务端发送请求,而长连接可以是客户端主动发送请求,也可以是服务端主动发。
  3. 两者的使用场景:短连接适用于客户端请求频率不高的场景,如浏览网页等。长连接适用于客户端与服务端通信频繁的场景,如聊天室,实时游戏等。

三、TCP业务逻辑实现

  • 业务目标: 编写TCP版本的字典客户端和字典服务器:

  • 业务实现逻辑: 和上面的 UDP业务逻辑实现一样,这里就不再赘述。

  • 业务实现:

代码如下:

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;public class TcpDirServer extends TcpEchoServer{private Map<String,String> hash = null;public TcpDirServer(int port) throws IOException {super(port);hash = new HashMap<>();hash.put("hello","你好");hash.put("cat","小猫");hash.put("dog","小狗");}@Overridepublic String process(String request) {return hash.getOrDefault(request,"该单词查询不到");}public static void main(String[] args) throws IOException {TcpDirServer server = new TcpDirServer(9090);server.start();}
}

效果如下:
在这里插入图片描述

结语:
其实写博客不仅仅是为了教大家,同时这也有利于我巩固知识点,和做一个学习的总结,由于作者水平有限,对文章有任何问题还请指出,非常感谢。如果大家有所收获的话还请不要吝啬你们的点赞收藏和关注,这可以激励我写出更加优秀的文章。

在这里插入图片描述

相关文章:

【JavaEE精炼宝库】 网络编程套接字——UDP业务逻辑 | TCP流套接字编程及业务逻辑实现

文章目录 一、UDP业务逻辑实现二、TCP流套接字编程2.1 API 介绍&#xff1a;2.1.1 ServerSocket&#xff1a;2.1.2 Socket&#xff1a; 2.2 Java流套接字通信模型&#xff1a;2.3 代码示例&#xff1a;2.3.1 TCP Echo Server&#xff1a;2.3.2 TCP Echo Client&#xff1a;2.3.…...

前端过渡动画

前端过渡动画 vue3 1、组件进入视口时向上移动且渐显 1、创建js文件addViewportEffect.js function slideDownEffect(element) {console.log("执行");element.style.transform translateY(0);element.style.opacity 1; }/*** 添加视口效果到指定的类名元素上。…...

actual combat 38 ——vue

vue-cli脚手架 创建命令&#xff1a;vue create 项目名称 eslint 如何关闭&#xff1f; vue.config.js文件中加 module.exports {lintOnSave: false }文件全代码&#xff1a; const { defineConfig } require(vue/cli-service) module.exports defineConfig({transpile…...

测试面试宝典(四十七)— 功能测试用例一般包含哪些内容

首先&#xff0c;明确测试用例的编号和名称&#xff0c;以便于识别和管理。 其次&#xff0c;详细描述测试的目标和背景&#xff0c;让其他人能够清楚了解该测试用例的目的和适用场景。 接着是测试的步骤&#xff0c;需要清晰、准确地列出每一个操作步骤&#xff0c;包括输入…...

rust_mac环境安装

在 macOS 上安装 Rust 很简单。你可以使用 Rust 提供的安装工具 rustup。下面是安装步骤&#xff1a; 打开终端。 运行以下命令以安装 rustup 和 Rust&#xff1a; curl --proto https --tlsv1.2 -sSf https://sh.rustup.rs | sh按照提示进行操作&#xff1a; 这个命令将下载并…...

【前端面试】七、算法-递归

常考算法 排序算法&#xff1a;快速排序、归并排序、堆排序等。 查找算法&#xff1a;二分查找、哈希表查找等。 动态规划&#xff1a;解决最优化问题&#xff0c;如斐波那契数列、最长公共子序列等。 图论算法&#xff1a;最短路径&#xff08;Dijkstra、Floyd-Warshall&am…...

CmsEasy逻辑漏洞--零元购

CmsEasy逻辑漏洞--零元购 选择购买MackBook 购买成功后会员中心发现多出8100快钱 然后就可以正常购买了...

Linux 内核源码分析---I/O 体系结构与访问设备

I/O 体系结构 与外设的通信通常称之为输入输出&#xff0c;一般都缩写为I/O。 在实现外设的I/O时&#xff0c;内核必须处理3个可能出现的问题&#xff1a; &#xff08;1&#xff09;必须根据具体的设备类型和模型&#xff0c;使用各种方法对硬件寻址&#xff1b; &#xff08…...

在cPanelWHM中如何重置 MySQL 用户帐户密码

更改MySQL用户账户密码非常简单。服务器管理员可以在WHM中编辑任何MySQL用户的帐户。cPanel用户可以编辑其帐户管理的数据库的密码。 在WHM中更改MySQL用户帐户密码 打开WHM&#xff0c;在侧边菜单中的SQL服务下选择“Change MySQLUser Password”。Hostease的服务器产品提供稳…...

软件测试基础1--功能测试

1、什么是软件测试&#xff1f; 软件是控制计算机硬件运行的工具。 软件测试&#xff1a;使用技术手段验证软件是否满足使用需求&#xff0c;为了发现软件功能和需求不相符合的地方&#xff0c;或者寻找实际输出和预期输出之间的差异。 软件测试的目的&#xff1a;减少软件缺陷…...

《计算机网络》(第8版)第9章 无线网络和移动网络 复习笔记

第 9 章 无线网络和移动网络 一、无线局域网 WLAN 1 无线局域网的组成 无线局域网提供移动接入的功能&#xff0c;可分为两大类&#xff1a;有固定基础设施的和无固定基础设 施的。 &#xff08;1&#xff09;IEEE 802.11 IEEE 802.11 是无线以太网的标准&#xff0c;是有固定…...

非负数、0和正整数 限制最大值且保留两位小数在elementpuls表单中正则验证

一、结构 <el-form-item label"单价&#xff1a;" prop"price"><el-inputv-model.trim"formData.price"placeholder"请输入"blur"formMethod.fixTwo"><template #append>(元)</template></el-i…...

Java多线程-----定时器(Timer)及其实现

目录 一.定时器简介&#xff1a; 二.定时器的构造方法与常见方法&#xff1a; 三.定时器的模拟实现&#xff1a; 思路分析&#xff1a; 代码实现&#xff1a; 在开发中&#xff0c;我们经常需要一些周期性的操作&#xff0c;例如每隔几分钟就进行某一项操作&#xff0c;这…...

【Linux修行路】进度条小程序

目录 ⛳️推荐 一、预备知识 1.1 回车换行 1.2 缓冲区 二、倒计时 2.1 注意事项 三、进度条 3.1 源代码 3.2 代码分析 3.2 实际使用场景 ⛳️推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家…...

网络安全入门教程(非常详细)从零基础入门到精通,看完这一篇就够了。

学前感言: 1.这是一条坚持的道路,三分钟的热情可以放弃往下看了.2.多练多想,不要离开了教程什么都不会了.最好看完教程自己独立完成技术方面的开发.3.有时多google,baidu,我们往往都遇不到好心的大神,谁会无聊天天给你做解答.4.遇到实在搞不懂的,可以先放放,以后再来解决. 基…...

【探索Linux】P.44(数据链路层 —— 以太网的帧格式 | MAC地址 | MTU | ARP协议)

阅读导航 引言一、认识以太网二、以太网的帧格式三、MAC地址四、MTU五、ARP协议温馨提示 引言 在深入探讨了网络层的IP协议之后&#xff0c;本文将带领读者进一步深入网络的底层——数据链路层。我们将详细解析以太网的帧格式&#xff0c;这是数据链路层传输数据的基本单元&am…...

<数据集>航拍行人识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;7482张 标注数量(xml文件个数)&#xff1a;7482 标注数量(txt文件个数)&#xff1a;7482 标注类别数&#xff1a;1 标注类别名称&#xff1a;[people, pedestrian] 序号类别名称图片数框数1people5226385602pedes…...

在 Windows 10 系统上部署 Medusa

先决条件 在安装 Medusa 之前&#xff0c;你需要确保已经安装了以下工具&#xff1a; Node.js: Medusa 需要 Node.js v16 或更高版本。你可以从 Node.js 官网下载并安装。Git: Git 用于从 GitHub 获取 Medusa 的源代码。你可以从 Git 官网下载并安装。PostgreSQL: Medusa 使用…...

Linux进程 (冯诺依曼体结构 管理 PCB 进程状态 僵尸进程 孤儿进程 运行阻塞挂起状态 进程优先级)

文章目录 一.冯诺依曼体系结构冯诺依曼结构能干什么&#xff1f; 二.操作系统概念结构图(不完整)为什么要有操作系统&#xff1f; 尝试理解操作系统管理结构图(完整)总结&#xff1a; 三.进程进程是什么&#xff1f;PCB为什么要有PCB&#xff1f; Linux中的PCB进程的task_struc…...

《LlamaIndex 之美》-01-LLM、Prompt、Embedding基础入门

在基于数据构建任何 LLM 应用程序时&#xff0c;选择合适的大型语言模型 &#xff08;LLM&#xff09; 是您需要考虑的首要步骤之一。 LLM 是 LlamaIndex 的核心组成部分。它们可以作为独立模块使用&#xff0c;也可以插入到其他核心 LlamaIndex 模块&#xff08;索引、检索器…...

在Windows上用C++部署YOLO11模型:从PyTorch训练到QT桌面应用的全流程避坑指南

工业级YOLO11模型C部署实战&#xff1a;从PyTorch到QT6.9的工程化落地指南 当Python训练的AI模型需要真正投入生产线时&#xff0c;C部署往往成为必经之路。去年在为某电子元件制造商部署电容极性检测系统时&#xff0c;我深刻体会到从Jupyter Notebook到稳定运行的Windows桌面…...

Retrieval-based Voice-Conversion-WebUI 专业指南:从认知到实践的语音转换技术全解

Retrieval-based Voice-Conversion-WebUI 专业指南&#xff1a;从认知到实践的语音转换技术全解 【免费下载链接】Retrieval-based-Voice-Conversion-WebUI 语音数据小于等于10分钟也可以用来训练一个优秀的变声模型&#xff01; 项目地址: https://gitcode.com/GitHub_Trend…...

RHEL 8 部署 Oracle 数据库

目录 一、目标与环境 二、Oracle安装包下载 官方下载地址&#xff08;推荐&#xff09; 三、安装详细步骤 第一阶段&#xff1a;系统准备&#xff08;全部以root用户操作&#xff09; 1. 安装必要的依赖包 2. 创建Oracle用户和组 3. 创建目录结构并设置权限 4. 配置系统…...

Python 数据统计分析全攻略:从基础到实战,一文掌握常用方法

在数据分析、机器学习、业务报表开发等场景中&#xff0c;数据统计分析是核心基础环节。Python 凭借丰富的第三方库&#xff0c;成为数据统计分析的首选工具。本文将系统梳理 Python 中数据统计分析的常用方法、核心库、实战代码&#xff0c;从基础统计量到高级分析&#xff0c…...

【已验证】基于STM32和HAL库的大夏龙雀BT311-10C02S蓝牙模块驱动

最近买了一个大夏龙雀家的蓝牙模块DX-BT311-10C02S&#xff0c;这个蓝牙是一款基于BLE 5.4规范的串口透传模块&#xff0c;支持AT指令配置、主从模式切换&#xff0c;非常适合与单片机搭配实现无线数据传输。如果是第一次买还是很便宜的&#xff0c;他家的模块有一说一是真的不…...

Docker+宝塔双方案:Nextcloud私有云盘从入门到企业级部署全攻略

Nextcloud企业级私有云部署双轨方案&#xff1a;Docker敏捷开发与宝塔生产环境实战指南 在数字化转型浪潮中&#xff0c;企业数据主权意识正在觉醒。Nextcloud作为开源的私有云解决方案&#xff0c;不仅提供了媲美商业云盘的功能体验&#xff0c;更让组织完全掌控数据流向。本文…...

别再拍脑袋定A/B测试样本量了!用Python/Excel/R三分钟算出靠谱结果

别再拍脑袋定A/B测试样本量了&#xff01;用Python/Excel/R三分钟算出靠谱结果 每次启动A/B测试前&#xff0c;团队总会陷入同样的争论&#xff1a;"这次实验需要多少流量才够&#xff1f;"产品经理凭经验说"10万用户应该够了"&#xff0c;运营同学翻出上次…...

终极指南:如何用Python脚本5分钟获取百度网盘真实下载链接

终极指南&#xff1a;如何用Python脚本5分钟获取百度网盘真实下载链接 【免费下载链接】baidu-wangpan-parse 获取百度网盘分享文件的下载地址 项目地址: https://gitcode.com/gh_mirrors/ba/baidu-wangpan-parse 你是否曾经为百度网盘的下载速度而烦恼&#xff1f;每次…...

手把手教你搞定VMware vSphere 7.0全家桶:从服务器RAID配置到vCenter上线的保姆级避坑指南

企业级虚拟化平台部署实战&#xff1a;从硬件配置到vSphere 7.0全栈落地指南 当企业IT基础设施面临数字化转型时&#xff0c;服务器虚拟化技术往往成为关键突破口。作为业界标杆的VMware vSphere解决方案&#xff0c;其7.0版本在性能、安全性和管理便捷性方面都有显著提升。本文…...

深入解析MCU Systick:从基础配置到精准延时与系统时间获取实战

1. Systick定时器基础解析 Systick是Cortex-M内核内置的24位递减计数器&#xff0c;堪称MCU的"心跳发生器"。我第一次在STM32项目中使用它时&#xff0c;就像发现了一个隐藏的瑞士军刀——简单却功能强大。这个看似简单的定时器&#xff0c;实际上承担着三大核心功能…...