tcp nio 服务端、客户端例子--参考《分布式Java应用:基础与实践》

Java:实现Nio方式实现tcp通信 1. 声明 当前内容主要为复习使用Nio方式实现tcp通信,实现tcp之间的信号传递和解析 2. Server端 /** * * @author hy * @createTime 2022-02-12 09:48:24 * @description 当前内容为使用Nio方式操作socket进行通信操作 * */ public class NioServerSocketTest { public static void main(String[] args) { int threadCou 阅读详情

 

 

参考《分布式java应用》tcp nio 服务端、客户端例子, 在基础主要做了以下调整:

1. 信息长度由定长(ByteBuffer长度)修正为可变长(即不再收长度限制)

2. 特殊错误处理:read Exception,opposite close Exception,select timeout Exception(网络超时)。

 

read Exception 与 opposite close Exception 的处理, 用于解决发现异常后造成程序的 while死循环。

select timeout Exception的处理, 用于对网络超时的支持。

 

/**
 *
 */

package distributed.tcpnio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;

/**
 * 实现TCP/IP+NIO 方式的系统间通讯的代码,服务器端:
 * SocketChannel和ServerSocketChannel两个关键的类,网络IO 的操作则改为通过ByteBuffer来实现。
 *
 * @author yangwm in Mar 22, 2010 5:52:58 PM
 */
public class ServerTcpNio {

    /**
     * create by yangwm in Mar 22, 2010 5:52:58 PM
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        int port = 9527;
        System.out.println("Server listen on port: " + port);
       
        Selector selector = Selector.open();
       
        ServerSocketChannel serverChannel = ServerSocketChannel.open();
        ServerSocket serverSocket = serverChannel.socket();
        serverSocket.bind(new InetSocketAddress(port));
        serverChannel.configureBlocking(false);
       
        serverChannel.register(selector, SelectionKey.OP_ACCEPT);
        while (true) {
            int nKeys = selector.select();
            if (nKeys > 0) {
                for (SelectionKey selectionKey : selector.selectedKeys()) {
                    if (selectionKey.isAcceptable()) {
                        ServerSocketChannel tempServerChannel = (ServerSocketChannel)selectionKey.channel();
                        SocketChannel socketChannel = tempServerChannel.accept();
                        if (socketChannel == null) {
                            continue;
                        }
                       
                        socketChannel.configureBlocking(false);
                        socketChannel.register(selector, SelectionKey.OP_READ);
                    } else if (selectionKey.isReadable()) {
                        //try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); }
                        SocketChannel socketChannel = (SocketChannel)selectionKey.channel();
                       
                        StringBuilder sb = new StringBuilder();
                        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
                        try {
                            int readBytes = 0;
                            int ret = 0;
                            while ((ret = socketChannel.read(byteBuffer)) > 0) {
                                readBytes += ret;
                                byteBuffer.flip();
                               
                                sb.append(Charset.forName("UTF-8").decode(byteBuffer).toString());
                               
                                byteBuffer.clear();
                            }
                           
                            if (readBytes == 0) {
                                /*
                                 * handle Exception
                                 */
                                System.err.println("handle opposite close Exception");
                                socketChannel.close();
                            }
                           
                           
                            String message = sb.toString();
                            System.out.println("Message from client: " + message);
                            if ("quit".equalsIgnoreCase(message.toString().trim())) {
                                System.out.println("Client has been quit!");
                               
                                socketChannel.close();
                            } else if ("serverquit".equalsIgnoreCase(message.trim())) {
                                System.out.println("Server has been shutdown!");
                               
                                socketChannel.close();
                                serverChannel.close();
                                selector.close();
                                System.exit(0);
                            } else {
                                String outMessage = "Server response:" + message;
                                socketChannel.write(Charset.forName("UTF-8").encode(outMessage));
                            }
                        } catch (IOException e) {
                            /*
                             * handle Exception
                             */
                            System.err.println("handle read Exception");
                            socketChannel.close();
                        } finally {
                            byteBuffer.clear();
                        }
                       
                    }
                }
                selector.selectedKeys().clear();
               
            }
        }
    }

}

 

 

/**
 *
 */
package distributed.tcpnio;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;

/**
 * 实现TCP/IP+NIO 方式的系统间通讯的代码,客户端:
 *
 * @author yangwm in Mar 22, 2010 10:19:51 PM
 */
public class ClientTcpNio {

    /**
     * create by yangwm in Mar 22, 2010 10:19:52 PM
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        String host = "127.0.0.1";
        int port = 9527;
       
        Selector selector = Selector.open();
       
        SocketChannel clientChannel = SocketChannel.open();
        clientChannel.configureBlocking(false);
        clientChannel.connect(new InetSocketAddress(host, port));
       
        clientChannel.register(selector, SelectionKey.OP_CONNECT);
       
        BufferedReader systemIn = new BufferedReader(new InputStreamReader(System.in));
        while (true) {
            if (clientChannel.isConnected()) {
                String command = systemIn.readLine();
                clientChannel.write(Charset.forName("UTF-8").encode(command));
               
                if (command == null || "quit".equalsIgnoreCase(command)) {
                    System.out.println("Client quit!");
                   
                    systemIn.close();
                    clientChannel.close();
                    selector.close();
                    System.exit(0);
                }
               
            }

            int nKeys = selector.select(3 * 1000);
            if (nKeys > 0) {
                for (SelectionKey selectionKey : selector.selectedKeys()) {
                    if (selectionKey.isConnectable()) {
                        SocketChannel socketChannel = (SocketChannel)selectionKey.channel();
                        socketChannel.configureBlocking(false);
                        socketChannel.register(selector, SelectionKey.OP_READ);
                        socketChannel.finishConnect();
                    } else if (selectionKey.isReadable()) {
                        SocketChannel socketChannel = (SocketChannel)selectionKey.channel();
                        StringBuilder sb = new StringBuilder();
                       
                        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
                        try {
                            int readBytes = 0;
                            int ret = 0;
                            while ((ret = socketChannel.read(byteBuffer)) > 0) {
                                readBytes += ret;
                                byteBuffer.flip();
                               
                                sb.append(Charset.forName("UTF-8").decode(byteBuffer).toString());
                               
                                byteBuffer.clear();
                            }
                           
                            if (readBytes == 0) {
                                /*
                                 * handle Exception
                                 */
                                System.err.println("handle opposite close Exception");
                                socketChannel.close();
                            }
                        } catch (IOException e) {
                            /*
                             * handle Exception
                             */
                            System.err.println("handle read Exception");
                            socketChannel.close();
                        } finally {
                            byteBuffer.clear();
                        }
                       
                        String message = sb.toString();
                        System.out.println(message);
                    }
                }
                selector.selectedKeys().clear();
               
            } else {
                /*
                 * handle Exception
                 */
                System.err.println("handle select timeout Exception");
                clientChannel.close();
            }
           
        }
    }

}

 

 

膜拜~ 终于拿到了美团老大哥分享的 Netty 源码剖析与应用 PDF Netty是一款基于NIO(非阻塞I/O)开发的网络框架,与传统BIO相比,它的并发性能得到了很大的提高,而且更加节省资源。Netty不仅封装了NIO操作的很多细节;在设计上还基于灵活、可扩展的事件驱动模型与高度可定制的线程模型,让Netty的应用更加灵活。作为一个被广泛使用的Java网络编程框架,Netty在互联网领域、大数据分布式计算领域、游戏行业、物联网行业等都得到了广泛的应用。如需获取原文档参考学习👉私信获取!目录​。... 阅读详情

相关推荐

netty原理简介及服务端、客户端详细代码

netty底层是对NIO的封装,封装成像AIO的样子、改进了ByteBuffer,很好用。

qq_38639813的博客 608

nio java tcp_【Java TCP/IP Socket】基于NIO的TCP通信(含代码)

NIO主要原理及使用NIO采取通道(Channel)和缓冲区(Buffer)来传输和保存数据,它是非阻塞式的I/O,即在等待连接、读写数据(这些都是在一线程以客户端的程序中会阻塞线程的操作)的时候,程序也可以做其他事情,以实现线程的异步操作。考虑一个即时消息服务器,可能有上千个客户端同时连接到服务器,但是在任何时刻只有非常少量的消息需要读取和分发(如果采用线程池或者一线程一客户端方式,则会非常浪费...

weixin_35110501的博客 345

傻白入门芯片设计,指令集架构、微架构、处理器内核(十一)

通俗理解指令集架构、微架构和处理器内核的关系

qq_46675545的博客 6017

Java NIO之TCP

流( TCP )信道详解 流信道有两个变体: SocketChannel 和 ServerSocketChannel 。像其对应的 Socket 一样,SocketChannel 是相互连接的终端进行通信的信道。 l  SocketChannel :创建,连接和关闭     static SocketChannel open(SocketAddress remote)     static

mInfoDavid的专栏 1004

unity人物刚体移动_Unity3D实现2D人物移动-总结篇

背景最近研究Unity3d,2d寻路的实现。所以又一次涉及到了角色坐标位移的问题。系统的对于角色鼠标点击移动这个简单问题进行整理和总结。本来就是一个简单的几何问题,结果发现已经有两个小坑,顺便填上,这里做下总结。实现需求:通过鼠标点击,控制2d角色移动,就是点哪里,角色向移动到哪里问题分解:按照时间进行动画分解,鼠标输入(动画开始)、平移(动画进行)、移动结束(动画结束)前提:这里前面的文章基本解...

weixin_39610366的博客 1277

Coze:手把手教你搭建 小红书二创 智能体

前一篇 “” ,讲了如何针对需求进行拆解,并拆解 ”小红书二创“ 智能体,分为四个内容模块。通过上述步骤,开始一步一步构建 “小红书二创” 智能体。用来测试的小红书地址:http://xhslink.com/a/quxWEDAj3J48。

保持敏感!保持学习! 1436

五、Java NIO 深入解读--TCP粘包、拆包

TCP 是面向连接的,面向流的,提供高可靠性服务。收发两端(客户端和服务器端)都要有一一成对的 socket,因此,发送端为了将多个发给接收端的包,更有效的发给对方,,将多次间隔较小且数据量小的数据,合并成一个大的数据块,然后进行封包。这样做虽然提高了效率,但是接收端就难于分辨出完整的数据包了,因为面向流的通信是无消息保护边界的。由于 TCP 无消息保护边界, 需要在接收端处理消息边界问题,也就是我们所说的粘包、拆包问题。

qq_41925134的博客 730

强化学习环境Gym库的介绍

Gym是一个用于进行强化学习实验的开源库,它提供了一个仿真环境,内置了多种仿真游戏,例如出租车游戏、悬崖游戏等,不同的游戏所用的网格、规则、奖励(reward)都不一样,适合为强化学习做测试。(1) 多种环境:Gym库内置了上百种实验环境,包括算法环境、简单文本环境、经典控制环境、Atari游戏环境、MuJoCo环境和机械控制环境等。(2) Gym提供多种环境供我们使用,这里以一个简单的CartPole-v0为例,首先导入gym库,然后创建一个CartPole-v0环境,通过调用gym.make方法实现。

ahah12345678的博客 2148

Java 网络编程之TCP(三):基于NIO实现服务端,BIO实现客户端

3.Selector:选择器,就是Linux 内核中的IO多路复用器,为了提高网络IO编程的效率,常用的有select, poll, epoll, 可以参考Linux对应系统调用。前面的文章,我们讲述了BIO的概念,以及编程模型,由于BIO中服务器端的一些阻塞的点,导致服务端对于每一个客户端连接,都要开辟一个线程来处理,导致资源浪费,效率低。先开启服务端,再开启两个客户端发送数据,服务端接受连接后,会打印当前接受到的客户端总数,然后轮询接收数据后打印;客户端:基于BIO,连接服务端,并发送数据。

u013771019的专栏 1159

以太网传输硬件设计大全

1.网线的介绍RJ45由插头和插做组成,也就是我们常说的网口和网线。RJ45 网线插头又称水晶头,共有八芯做成。RJ45网络传输线分为直通线、交叉线和全反线。直通线用于异种网络设备之间的互连,例如,计算机与交换机。交叉线用于同种网络设备之间的互连,例如,计算机与计算机。全反线用于超级终端与网络设备的控制物理接口之间的连接。下面将介绍一下各线的作用和区别。1.直通线:又叫正线或标准线,两端采用568B做线标准,注意两端都是同样的线序且一一对应。直通线是应用最广泛,现在最常用的线。

weixin_45365488的博客 6751

五大经典遥感数据集对比:LoveDA、Potsdam、Toronto、Vaihingen、Massachusetts Roads选哪个?

本文深度对比了LoveDA、Potsdam、Vaihingen、Toronto和Massachusetts Roads五大经典遥感数据集。针对城市监测、道路提取、土地分类等不同任务,从分辨率、标注质量、数据规模及场景多样性等核心维度进行分析,为研究者根据项目目标、硬件条件与应用场景选择最合适的遥感数据集提供决策指南。

weixin_29057065的博客 237

分布式通信之Java IO

IO IO概述 1.首先注意IO是InputStream(输入流)和OutputStream(输出流)的缩写 2.这里的InputStream实际上是一个集合,很多集成InputStream的子类都是; 3.我们这里的InputStream(输入流)和OutputStream(输出流)是针对的系统内存来讲的; 将数据(本地磁盘或者网络中的数据)读取写入内存,叫输入; 将内存中的数据...

高新富的博客 505

Pytorch入门实战(7):基于BERT实现文本隐喻二分类(Kaggle入门题目)

Bert入门实战,文本二分类问题

iioSnail的博客 4056

hbase 客户端_HBase源码:网络通信篇

导读在分布式存储系统中,节点间的通信是很重要的组成部分。如果不了解系统中的通信机制,就无法真正理解一套完整的读写流程。由于HBase年代久远(1.2.0版本),暂时使用的还是java原生的NIO,并没有使用Netty之类的框架。本篇就来介绍下HBase中基于NIO的RPC通信。1 RPC=protobuf+nioHBase基于protobuf+nio实现rpc:基于protobuf预定义消息格式,...

weixin_39887577的博客 361

基于激光雷达与视觉融合的四旋翼无人机室内避障方法研究

本文研究了一种基于激光雷达与视觉融合的四旋翼无人机室内避障方法。针对单一传感器在室内环境中的局限性,提出通过激光雷达提供精确几何距离、视觉相机补充语义信息的融合方案。研究内容包括:搭建ROS硬件平台集成单目相机与2D激光雷达;设计基于扩展卡尔曼滤波的传感器融合模型;改进VFH算法结合视觉深度图进行路径规划。实验验证表明,该方法在复杂室内环境下具有较高的鲁棒性、实时性与避障成功率,为解决无GPS信号环境下的无人机自主导航问题提供了有效方案。

huanghm88的专栏 348

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

java 分布式rpc调用_如何实现一个分布式RPC框架

远程过程调用(Remote Procedure Call,RPC)是一个计算机通信协议。该协议允许运行于一台计算机的程序调用另一台计算机的子程序,而程序员无需额外地为这个交互作用编程。RPC的主要目标是让构建分布式应用更加容易,在提供强大的远程调用能力的同时不损失本地调用的语义的简洁性。趁实习前的这段业余时间,我实现了一个轻量级的分布式RPC框架,名字叫做 buddha,代码量不大,但是麻雀虽小却...

weixin_32380501的博客 228

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

还没使用过消息队列?这一份书单值得你好好看看!

点击蓝色“程序员书单”关注我哟 加个“星标”,每天带你读好书! Java工程师往往容易忽视的一块知识点,其实就是Java网络编程,为什么呢,因为如果我想写一个Java Web项目,我只要用SSM就可以轻松搞定,写好我们的controller、service和dao就可以了,也就是只需要关心业务逻辑,不需要关心前端请求的路由、甚至是后端的负载均衡和网络请求处理,因为这些东西很多时候都被Nginx和Tomcat给吃掉了,Nginx帮我们做好了负载均衡,Tomcat则帮我们完成TCP连接的建立,HT.

程序员书单 838

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

如何实现一个分布式 RPC 框架

远程过程调用(Remote Procedure Call,RPC)是一个计算机通信协议。该协议允许运行于一台计算机的程序调用另一台计算机的子程序,而程序员无需额外地为这个交互作用编程。RPC的主要目标是让构建分布式应用更加容易,在提供强大的远程调用能力的同时不损失本地调用的语义的简洁性。 趁实习前的这段业余时间,我实现了一个轻量级的分布式RPC框架,名字叫做 buddha,代码量不大,但是麻

GarfieldEr007的专栏 979

如何实现一个分布式RPC框架

远程过程调用(Remote Procedure Call,RPC)是一个计算机通信协议。该协议允许运行于一台计算机的程序调用另一台计算机的子程序,而程序员无需额外地为这个交互作用编程。RPC的主要目标是让构建分布式应用更加容易,在提供强大的远程调用能力的同时不损失本地调用的语义的简洁性。 趁实习前的这段业余时间,我实现了一个轻量级的分布式RPC框架,名字叫做 buddha(htt

程序文摘(CodeDigest) 1228

最新网络应用扛把子:阿里高工手写Netty速成手册,带你走向实战(1),成功入职阿里月薪45K

为了让更多的开发人员学习好Netty,特此公布:阿里高工手写的13万字的“Netty速成手册”。面试前做足功夫,让你面试成功率提升一截,这里一份热门350道一线互联网常问面试题及答案助你拿offer。Netty协议栈功能设计+Netty协议栈开发+运行协议栈**)**第三部分:高级篇 Netty 多协议开发和应用。第二部分:中级篇 Netty 编解码开发。第四部分 Netty 功能介绍和源码分析。第一部分:基础 走进Java NIO。

2401_84584338的博客 643

面试官:讲讲七层网络模型与TCP三次握手与四次挥手?

目前,很多面试场景都开始重视基础知识的考察,比如:操作系统、IO(BIO、NIO、AIO)、网络、数据结构和算法等等。这不,就有小伙伴被面试官问到了网络的七层模型和TCP三次握手与四次...

dabaoshiwode的博客 470

构建高性能网络服务:从 Socket 原理到 Netty 应用实践

Netty 是 Java 网络编程领域最流行的 NIO 框架,其**简单易用**和**高扩展性**使其成为构建高并发、高吞吐量网络服务的首选。本文通过对 Netty 主要组件、常见问题及解决方案的详细讲解,帮助读者了解并掌握 Netty 的开发方法。

qq_36534560的博客 1040

netty基础概念

参考对于Netty的十一个疑问 先理解相关概念 一、阻塞与非阻塞:数据没准备好,要不要死等? 阻塞:1、读取数据没准备好时,等待数据返回(死等);2、写操作时缓冲区数据满了,等待数据被消费(死等); 非阻塞:读取数据没准备好或写缓冲满时,都直接返回。 二、同步与异步:数据准备好后,谁来主动操作? 数据准备就绪后,数据操作谁来完成? 数据准备就绪后需要调用方主动来读就是同步;数据准备...

越自律越自由 993

Netty(四)——HTTP服务端之例

        HTTP(HyperText Transfer Protocol,超文本传输协议)是因特网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准。我们用的tomcat、jetty、jobss等各种服务器,其实就是一个服务端容器,方便我们直接部署我们应用,让用户通过使用客户端(WEB浏览器、手机H5、app等)借住HTTP协议,来完成信息的提交和获取。这篇文章简单总结一...

学会改变自己——才能突破 1815

Java后端开发-随记

不知道要分享啥,把之前整理的一份稳定CV下;近期在胡天乱想啥都想学习一下~,感觉编程语言、中间价框架都是基于需求主导推进~后面深度研究研究Ai,把mac的性能释放出来~下面的内容是我前一月的信息汇总,很多地方会有不足,仅供参考。当时是我想到啥写啥,也没有进行很深度地修订!

NEWstyle_的博客 824
上一篇: Java并发编程--三个线程顺序打印ABC
下一篇: 体验eclipse4
yangwm
博客等级 码龄20年 38粉丝 55原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值