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

JAVA异步的TCP 通讯-客户端

一、客户端代码示例

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class AdvancedAsyncTCPClient {private static final String SERVER_HOST = "localhost";private static final int SERVER_PORT = 8888;private static final int BUFFER_SIZE = 1024;private final AsynchronousSocketChannel clientChannel;private final ExecutorService threadPool;public AdvancedAsyncTCPClient() throws IOException {// 创建异步套接字通道clientChannel = AsynchronousSocketChannel.open();// 创建一个固定大小的线程池,用于处理业务逻辑threadPool = Executors.newFixedThreadPool(5);}public void connect() {// 异步连接到服务器clientChannel.connect(new InetSocketAddress(SERVER_HOST, SERVER_PORT), null, new CompletionHandler<Void, Void>() {@Overridepublic void completed(Void result, Void attachment) {System.out.println("Connected to server: " + SERVER_HOST + ":" + SERVER_PORT);// 连接成功后开始读取服务器数据startReading();// 发送初始消息sendMessage("Hello, server!");}@Overridepublic void failed(Throwable exc, Void attachment) {System.err.println("Failed to connect to server: " + exc.getMessage());closeChannel();}});}private void startReading() {ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);// 异步读取服务器数据clientChannel.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() {@Overridepublic void completed(Integer bytesRead, ByteBuffer buffer) {if (bytesRead > 0) {buffer.flip();byte[] data = new byte[buffer.remaining()];buffer.get(data);String message = new String(data);System.out.println("Received message from server: " + message);// 继续读取服务器数据buffer.clear();clientChannel.read(buffer, buffer, this);} else if (bytesRead == -1) {// 服务器关闭连接System.out.println("Server closed the connection");closeChannel();}}@Overridepublic void failed(Throwable exc, ByteBuffer buffer) {System.err.println("Failed to read data from server: " + exc.getMessage());closeChannel();}});}public void sendMessage(String message) {ByteBuffer buffer = ByteBuffer.wrap(message.getBytes());// 异步发送消息到服务器clientChannel.write(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() {@Overridepublic void completed(Integer bytesWritten, ByteBuffer buffer) {if (buffer.hasRemaining()) {// 如果还有数据未发送完,继续发送clientChannel.write(buffer, buffer, this);} else {System.out.println("Message sent to server: " + message);}}@Overridepublic void failed(Throwable exc, ByteBuffer buffer) {System.err.println("Failed to send message to server: " + exc.getMessage());closeChannel();}});}private void closeChannel() {try {System.out.println("Closing client connection");clientChannel.close();threadPool.shutdown();} catch (IOException e) {System.err.println("Error closing client channel: " + e.getMessage());}}public static void main(String[] args) {try {AdvancedAsyncTCPClient client = new AdvancedAsyncTCPClient();client.connect();} catch (IOException e) {System.err.println("Error creating client: " + e.getMessage());}}
}

二、代码分析

AdvancedAsyncTCPClient 类

  1. 构造函数:创建 AsynchronousSocketChannel 并初始化一个固定大小的线程池

  2. connect() 方法:异步连接到服务器,连接成功后开始读取服务器数据并发送初始消息。

  3. startReading() 方法:异步读取服务器发送的数据,使用 CompletionHandler 处理读取结果。

  4. sendMessage() 方法:异步发送消息到服务器,处理可能的未发送完的数据。

  5. closeChannel() 方法:关闭客户端通道并关闭线程池,处理关闭过程中可能出现的异常。

CompletionHandler

  1. 在 connect()startReading() 和 sendMessage() 方法中使用 CompletionHandler 来处理异步操作的完成结果。
  2. completed() 方法处理操作成功的情况,failed() 方法处理操作失败的情况。

线程池

        1.使用 Executors.newFixedThreadPool(5) 创建一个固定大小的线程池,用于处理业务逻辑,避免阻塞 I/O 操作。

三、优点

  • 异步 I/O:利用 Java NIO 2 的异步 I/O 特性,提高了客户端的并发处理能力。
  • 线程池:使用线程池处理业务逻辑,减少了线程创建和销毁的开销。
  • 异常处理:对各种异常情况进行了处理,增强了代码的健壮性。
  • 资源管理:在关闭客户端时,正确关闭客户端通道和线程池,避免资源泄漏。

四、注意事项

  • 该示例假设服务器运行在 localhost 的 8888 端口,你可以根据实际情况修改 SERVER_HOST 和 SERVER_PORT
  • 此代码只是一个基础示例,实际应用中可能需要根据具体需求进行扩展,如处理更复杂的消息格式、实现重连机制等。

相关文章:

JAVA异步的TCP 通讯-客户端

一、客户端代码示例 import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.AsynchronousSocketChannel; import java.nio.channels.CompletionHandler; import java.util.concurrent.ExecutorService; impo…...

python:递归函数与lambda函数

递归函数&#xff1a;1.函数内调用自己 2.有一个出口 1.递归 一.有出口时 def sum(num):if num1:return 1return numsum(num-1) asum(3) print(a) #num3 3sum(2) #num2 2sum(1) #num1是返回1 #即3sum(2&#xff09;即32sum(1)即321运行结果 6 二.无出口时 def sum(num)…...

G1相对于CMS的的优势

1.G1在压缩空间方面有优势。 2.G1通过将内存空间分成区域&#xff08;Region&#xff09;的方式避免内存碎片问题 3.Eden、Survivor、Old区不再固定&#xff0c;在内存使用率上来说更灵活 4.G1可以通过设置预期停顿时间&#xff08;Pause Time&#xff09;来控制垃圾收集时间…...

java进阶之并发编程一ReentrantLock的实际应用和线程中断EXAMPLE

引言:继上一篇ReentrantLock的介绍来做俩个小demo。 实现3个线程分别打印指定数字和线程死锁进行线程中断。 上一篇:<<java进阶之并发编程一ReentrantLock同步锁的学习和syncthronized的区别>> **demo1:**ReentrantLock搭配三个线程分别打印指定的数字,直接上代…...

消费kafka消息示例

以下是使用 Java 结合 Spring Kafka 框架来监听 updated-topic-test 这个 Kafka Topic 的详细实现步骤及代码示例&#xff0c;用于捕获人员信息变更的事件。 1. 添加依赖 在 pom.xml 文件中添加 Spring Kafka 相关依赖&#xff1a; <dependencies><!-- Spring Boot…...

分享2款 .NET 开源且强大的翻译工具

前言 对于程序员而言永远都无法逃避和英文打交道&#xff0c;今天大姚给大家分享2款 .NET 开源、功能强大的翻译工具&#xff0c;希望可以帮助到有需要的同学。 STranslate STranslate是一款由WPF开源的、免费的&#xff08;MIT License&#xff09;、即开即用、即用即走的翻…...

SpringBoot+Dubbo+zookeeper 急速入门案例

项目目录结构&#xff1a; 第一步&#xff1a;创建一个SpringBoot项目&#xff0c;这里选择Maven项目或者Spring Initializer都可以&#xff0c;这里创建了一个Maven项目&#xff08;SpringBoot-Dubbo&#xff09;&#xff0c;pom.xml文件如下&#xff1a; <?xml versio…...

Java 面试之结束问答

技术优化 线程池优化 设置最大线程数设置最小核心线程数设置额外线程存活时间选择线程池队列选择合适的线程池选择合适的饱和策略 锁优化 尽量不要锁住方法缩小同步代码块&#xff0c;只锁数据锁中尽量不要再包含锁将锁私有化&#xff0c;在内部管理锁进行适当的锁分解 HT…...

[LeetCode] 二叉树 I — 深度优先遍历(前中后序遍历) | 广度优先遍历(层序遍历):递归法迭代法

二叉树 基础知识深度优先遍历递归法迭代法&#xff08;栈&#xff09;144# 二叉树的前序遍历94# 二叉树的中序遍历145# 二叉树的后序遍历 广度优先遍历递归法迭代法&#xff08;队列&#xff09;102# 二叉树的层序遍历107# 二叉树的层序遍历 II199# 二叉树的右视图637# 二叉树的…...

主动管理的基本概念

什么是主动管理&#xff1f; 主动管理&#xff0c;又称主动投资&#xff0c;是一种投资策略&#xff0c;投资组合经理进行特定投资的目的是超越投资基准指数。与被动管理不同&#xff0c;主动管理者依靠分析研究、预测以及自己的判断和经验来决定买入、持有和卖出哪些证券。“…...

Python aiortc API

本研究的主要目的是基于Python aiortc api实现抓取本地设备&#xff08;摄像机、麦克风&#xff09;媒体流实现Web端预览。本文章仅仅描述实现思路&#xff0c;索要源码请私信我。 demo-server解耦 原始代码解析 http服务器端 import argparse import asyncio import json…...

OpenCV4,快速入门,第二讲:图像色彩空间转换

文章目录 引言一、色彩空间概述1.1 RGB与HSV的区别1.2 HSV的详细含义cvtColor二、cvtColor函数详解2.1 函数原型2.2 参数说明2.3 使用示例三、imwrite函数详解3.1 函数原型3.2 参数说明3.3 使用示例四、完整示例代码五、应用场景与注意事项5.1 HSV的典型应用5.2 注意事项结语引…...

86.(2)攻防世界 WEB PHP2

之前做过&#xff0c;回顾一遍&#xff0c;详解见下面这篇博客 29.攻防世界PHP2-CSDN博客 既然是代码审计题目&#xff0c;打开后又不显示代码&#xff0c;肯定在文件里 <?php // 首先检查通过 GET 请求传递的名为 "id" 的参数值是否严格等于字符串 "admi…...

【Leetcode 每日一题】90. 子集 II

问题背景 给你一个整数数组 n u m s nums nums&#xff0c;其中可能包含重复元素&#xff0c;请你返回该数组所有可能的 子集&#xff08;幂集&#xff09;。 解集 不能 包含重复的子集。返回的解集中&#xff0c;子集可以按 任意顺序 排列。 数据约束 ● 1 ≤ n u m s . …...

RK3588——解决Linux系统触摸屏坐标方向相反问题

问题描述&#xff1a;触摸正常产生中断&#xff0c;但系统上报的触摸坐标不正确&#xff0c;是反向的坐标。 解决办法通过修改设备树添加属性翻转坐标。 注&#xff1a;需确认对应的驱动是否有解析该属性的具体内容&#xff0c;否则仍然无法生效。...

面对全球化的泼天流量,出海企业如何观测多地域网络质量?

作者&#xff1a;俞嵩、白玙 泼天富贵背后&#xff0c;技术挑战接踵而至 随着全球化进程&#xff0c;出海、全球化成为很多 Toc 产品的必经之路&#xff0c;保障不同地域、不同网络环境的一致的用户体验成为全球化应用的不得不面对的问题。在跨运营商、跨地域的网络环境中&am…...

YOLOv11实时目标检测 | 摄像头视频图片文件检测

在上篇文章中YOLO11环境部署 || 从检测到训练https://blog.csdn.net/2301_79442295/article/details/145414103#comments_36164492&#xff0c;我们详细探讨了YOLO11的部署以及推理训练&#xff0c;但是评论区的观众老爷就说了&#xff1a;“博主博主&#xff0c;你这个只能推理…...

PyQt6/PySide6 的 QPushButton 类

QPushButton 是 PyQt6 或 PySide6 库中用于创建按钮控件的类。按钮是用户界面中最常用的控件之一&#xff0c;用于触发特定的动作或事件。QPushButton 提供了丰富的功能和灵活性&#xff0c;使得开发者可以轻松地创建各种类型的按钮。下面我将详细介绍 QPushButton 的主要特性及…...

libdrm移植到arm设备

一、环境资源要求 下载libdrm Index of /libdrm 这边使用的是2.4.114版本&#xff0c;版本太高对meson版本要求也很高&#xff0c;为了省事用apt安装meson就不用太高版本了&#xff0c;1.x版本虽然使用makefile编译方便但是太老&#xff0c;对应用支持不太好。 https://dri…...

自定义序列化数据类型

目录 1. WritableComparable1.1 Writable1.2 Comparable1.3 IntWritable 2. 自定义序列化数据类型RectangleWritable3. 矩形面积计算3.1 Map3.2 Reduce 4. 代码和结果4.1 pom.xml中依赖配置4.2 工具类util4.3 矩形面积计算4.4 结果 参考 本文引用的Apache Hadoop源代码基于Apac…...

【Linux网络编程】:URL(encode),HTTP协议,telnet工具

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;Linux网络编程 &#x1f337;追光的人&#xff0c;终会万丈光芒 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 ​ Linux网络编程笔记&#xff1a; https://mp.csdn…...

C语言基础系列【3】VSCode使用

前面我们提到过VSCode有多么的好用&#xff0c;本文主要介绍如何使用VSCode编译运行C语言代码。 安装 首先去官网&#xff08;https://code.visualstudio.com/&#xff09;下载安装包&#xff0c;点击Download for Windows 获取安装包后&#xff0c;一路点击Next就可以。 配…...

学前端框架之前,你需要先理解 MVC

MVC 软件架构设计模式鼎鼎大名&#xff0c;相信你已经听说过了&#xff0c;但你确定自己已经完全理解到 MVC 的精髓了吗&#xff1f; 如果你是新同学&#xff0c;没听过 MVC&#xff0c;那可以到网上搜一些文章来看看&#xff0c;不过你要有心理准备&#xff0c;那些文章大多都…...

Mysql:数据库

Mysql 一、数据库概念&#xff1f;二、MySQL架构三、SQL语句分类四、数据库操作4.1 数据库创建4.2 数据库字符集和校验规则4.3 数据库修改4.4 数据库删除4.4 数据库备份和恢复其他 五、表操作5.1 创建表5.2 修改表5.3 删除表 六、表的增删改查6.1 Create(创建):数据新增1&#…...

python的函数介绍

一.定义和调用函数 1.定义函数 在 Python 中&#xff0c;使用 def 关键字来定义一个函数。函数可以包含参数&#xff0c;也可以包含返回值 基本语法 def function_name(parameters):"""docstring"""# Function bodyreturn resultdef greet(n…...

要完成使用MLflow比较模型运行、选择模型并将其部署到REST API的教程

要完成使用MLflow比较模型运行、选择模型并将其部署到REST API的教程&#xff0c;请按照以下有序步骤操作&#xff1a; 设置环境 导出MLflow跟踪URI&#xff1a;设置环境变量以指向您的MLflow跟踪服务。export MLFLOW_TRACKING_URIyour-organizations-MLflow-server-url 加载数…...

Windows Docker笔记-简介摘录

Docker是一个开源的容器化平台&#xff0c;可以帮助开发人员将应用程序与其依赖项打包在一个独立的容器中&#xff0c;然后在任何安装的Docker的环境中快速、可靠地运行。 几个基本概念和优势&#xff1a; 容器&#xff1a;容器是一个轻量级、独立的运行环境&#xff0c;包含了…...

MVC 文件夹:架构之美与实际应用

MVC 文件夹:架构之美与实际应用 引言 MVC(Model-View-Controller)是一种设计模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种架构模式不仅提高了代码的可维护性和可扩展性,而且使得开发流程更加清晰。本文将深入探讨MVC文…...

AI透明化与全球政治格局的发展:如何避免AI被人为操控

在现代社会&#xff0c;人工智能&#xff08;AI&#xff09;已经逐渐渗透到我们的日常生活中&#xff0c;尤其是在社交平台和信息传播领域。虽然AI可以极大地推动社会发展&#xff0c;但也潜藏着被恶意操控的风险。最令人担忧的是&#xff0c;某些势力可能通过操控AI来操控公众…...

ubuntu 网络管理--wpa_supplicant、udhcpc

ubuntu 网络管理--wpa_supplicant 1 介绍wpa_supplicant 无线认证wpa_passphrase 配置工具 NetworkManager 网络管理udhcpc 与 dhclient对比dhclient概述主要功能 udhcpc概述主要功能 2 联系依赖关系配置文件 3 区别4 如何选择5 示例使用 wpa_supplicant 手动连接无线网络使用 …...