Java——基于java自身包实现消息系统间的通信(TCP/IP+NIO)
/** * Created by LiuHuiChao on 2016/11/15. * description:based on TCP/IP+NIO to deliver the message */ public class TCP_IP_NIO { @Test public void clientStart() throws IOException { SocketChannel channel=SocketChannel.open(); channel.configureBlocking(false);//设置为非阻塞方式 SocketAddress remote=new InetSocketAddress("127.0.0.1",8888); channel.connect(remote); Selector selector= Selector.open(); channel.register(selector, SelectionKey.OP_CONNECT); /**阻塞至有感兴趣的IO事件发生,或到达超时时间,如果希望一直等至有感兴趣的IO事件发生,可调用无参数select方法, * 如果希望不阻塞直接返回目前是否有感兴趣的事件发生,可以调用selectNow方法 * */ int nkeys=selector.select();//如果nkeys大于0,说明有感兴趣的IO事件发生 SelectionKey selectionKey=null; if(nkeys>0){ Set<SelectionKey> keys=selector.selectedKeys(); for(SelectionKey key : keys){ //对于发生连接的事件 if(key.isConnectable()){ SocketChannel sc= (SocketChannel) key.channel(); sc.configureBlocking(false); /**注册感兴趣的IO读事件,通常不直接注册写事件,在发送缓冲区未满的情况下,一直是可写的, * 因此,如注册了写事件,而又不用写数据,很容易造成CUP消耗100%的情况; * */ selectionKey=sc.register(selector,SelectionKey.OP_READ); sc.finishConnect(); }else if(key.isReadable()){/**有流可读*/ ByteBuffer byteBuffer=ByteBuffer.allocate(1024); SocketChannel sc= (SocketChannel) key.channel(); int readBytes=0; try{ int ret=0; try{ /**读取目前可读的流,sc.read返回的为成功复制到bytebuffer中的字节数; * 此步骤为阻塞操作,值可能为0;当已经是流的结尾时,返回-1 * */ while((ret=sc.read(byteBuffer))>0){ readBytes+=ret; } }finally{ byteBuffer.flip(); } }finally{ if(byteBuffer!=null){ byteBuffer.clear(); } } }else if(key.isWritable()){/**可写入流*/ //取消对OP_WRITE事件的注册 key.interestOps(key.interestOps()&(~selectionKey.OP_WRITE)); SocketChannel sc= (SocketChannel) key.channel(); /**此步骤为阻塞操作,直到写入操作系统发送缓冲区或网路IO出现异常,返回的为成功写入的字节数,当操作系统的发送缓冲区已满,此处返回0*/ ByteBuffer byteBuffer=ByteBuffer.allocate(1024); sc.read(byteBuffer); int writtenedSize=sc.write(byteBuffer); //如未写入,则继续注册感兴趣的OP_WRITE事件 if(writtenedSize==0){ key.interestOps(key.interestOps() | selectionKey.OP_WRITE); } } } selector.selectedKeys().clear(); } } @Test public void serverStart() throws IOException { ServerSocketChannel ssc=ServerSocketChannel.open(); ServerSocket serverSocket=ssc.socket(); //绑定要监听的端口 serverSocket.bind(new InetSocketAddress(8888)); ssc.configureBlocking(false); Selector selector= Selector.open(); //注册感兴趣的事件连接 ssc.register(selector,SelectionKey.OP_ACCEPT); /** * 之后采取和客户端相同的方式对selector.select进行轮询。。。但是要增加一个key.isAcceptable的处理。。。 * */ } }
Java——基于java自身包实现消息系统间的通信(TCP/IP+NIO)的更多相关文章
- Java——基于java自身包实现消息系统间的通信(TCP/IP+BIO)
最近看到阿里的一位童鞋写的一本关于分布式的书,感觉不错,准备把这本书上基础的代码都写一写. /** * Created by LiuHuiChao on 2016/11/15. * descripti ...
- Java多线程之线程的状态以及线程间协作通信导致的线程状态转换
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6561589.html 一:线程的状态以及变化图 Java中线程中状态可分为五种:New(新建状态),Ru ...
- 《Wireshark数据包分析实战》 - http背后,tcp/ip抓包分析
作为网络开发人员,使用fiddler无疑是最好的选择,方便易用功能强. 但是什么作为爱学习的同学,是不应该止步于http协议的,学习wireshark则可以满足这方面的需求.wireshark作为抓取 ...
- Java基于SSM的个人博客系统(源码 包含前后台)
@ 目录 系统简介 系统运行截图 核心代码 写在最后 系统简介 技术点:Java.JSP.SSM框架,实现了个人博客系统 用户角色分为:普通用户.管理员.系统管理员 功能:发博客.博客分类.博客删除. ...
- Java并发读书笔记:如何实现线程间正确通信
目录 一.synchronized 与 volatile 二.等待/通知机制 等待 通知 面试常问的几个问题 sleep方法和wait方法的区别 关于放弃对象监视器 三.等待通知典型 生产者消费者模型 ...
- Java通过wait()和notifyAll()方法实现线程间的通信
Java代码(使用了2个内部类): package Threads; import java.util.LinkedList; /** * Created by Frank */ public cla ...
- Java核心知识点学习----多线程并发之线程间的通信,notify,wait
1.需求: 子线程循环10次,主线程循环100次,这样间隔循环50次. 2.实现: package com.amos.concurrent; /** * @ClassName: ThreadSynch ...
- 分布式架构从零开始========》【基于Java自身技术实现消息方式的系统间通信】
基于Java自身包实现消息方式的系统间通信的方式有:TCP/IP+BIO,TCP/IP+NIO,UDP/IP+BIO,UDP/IP+NIO.下面就这4种类型一一做个详细的介绍: 一.TCP/IP+BI ...
- Java与C++进行系统间交互:Protocol Buffer
在一次项目中,因笔者负责的java端应用需要与公司C++系统进行交互,公司选定Protocol Buffer方案,故简单的了解一下 有需要的可以看一下其他作者的文章,了解一下Protobuf: htt ...
随机推荐
- MySQL5.7 不同操作系统下的主从配置
1. 服务器信息 1.1 Ubuntu 17.0.4 (Master服务器) MySQL版本: 5.7.20 主数据库:dslbcp IP: 192.168.12.130 3306 1.2 Wind ...
- 一步步入门编写PHP扩展
1.写在最前 随着互联网飞速发展,lamp架构的流行,php支持的扩展也越来越多,这样直接促进了php的发展. 但是php也有脚本语言不可避免的问题,性能比例如C等编译型语言相差甚多,所以在考虑性能问 ...
- Linux内存管理学习笔记——内存寻址
最近开始想稍微深入一点地学习Linux内核,主要参考内容是<深入理解Linux内核>和<深入理解Linux内核架构>以及源码,经验有限,只能分析出有限的内容,看完这遍以后再更深 ...
- linux内核中网络文件系统的注册初始化
针对内核3.9 系统开启时,会使用init/main.c,然后再里面调用kernel_init(),在里面会再调用do_basic_setup(),调用do_initcalls(),调用do_one_ ...
- geomesa hbase geoserver
在geoserver中配置hbase ln -s /root/hbase/hbase-1.4.8/conf/hbase-site.xml /root/tomcat/apache-tomcat-7.0. ...
- linux内核追踪(trace)(QEMU+gdb)
1.引言 Linux内核是一个很大的模块,如果只是看源码有时会难以理解Linux内核的一些代码设计情况,如果可以结合Linux内核运行同时阅读源码再好不过,本文大致介绍Linux内核追踪方式,采用工具 ...
- java 网站源码 六套模版 兼容手机平板PC freemaker 静态引擎 在线编辑模版
官网 http://www.fhadmin.org/ 系统介绍: 1.网站后台采用主流的 SSM 框架 jsp JSTL,网站后台采用freemaker静态化模版引擎生成html 2.因为是生成的ht ...
- CentOS 7紧急救援模式修改root用户密码的方法
最近无聊在网上搜索linux系统root用户密码破解方法,看来很多朋友的博文,同时也试了一下,但是感觉他们写的还是不是很清晰.简洁,因此自己就心血来潮写了这篇博文,提供一个比较清晰的思路给新手,如果有 ...
- JQuery简单总结(思维导图)
- vue bus方式解决非父子组件间的传值
对于非父子组件之间的传值 通常使用VUEX 和总线等方式解决 这里我聊聊发布订阅模式(总线) <body> <div class="app"> <ch ...