- 浏览: 280935 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (153)
- unix (2)
- sql (3)
- pl/sql (1)
- cvs (1)
- core java (36)
- OOAD UML (1)
- XML (4)
- JDBC (5)
- Hibernate (1)
- HTML (1)
- javascript (2)
- servlet (2)
- jsp (1)
- AJAX (1)
- Struts1.x (0)
- Struts2.x (5)
- Spring (6)
- EJB (2)
- WebService (2)
- 生活 (2)
- 感情 (0)
- 其他 (9)
- jbuilder2005 (1)
- db2 (1)
- groovy (1)
- 银行业务 (1)
- Android (9)
- java设计模式 (8)
- J2SE (2)
- DataBase (4)
- lucene (2)
- java卡 (1)
- flex (3)
- 烹饪 (1)
- 测试 (1)
- java硬件 (2)
- upnp (3)
- S2SH lib (1)
- nio CshBBrain (1)
- socket (1)
- 二维码 (1)
- 热加载 (1)
- hadoop (3)
- NIO (1)
- 新银行前置机预研 (1)
- springmvc3 (1)
- jvm (1)
- sf (0)
最新评论
-
niwowl:
可以!
gson使用在android使用例子 -
smallbee:
xin_jmail 写道首先感谢楼主的文章,让我知道了lock ...
java ReentrantLock Condition调试记录 -
xin_jmail:
首先感谢楼主的文章,让我知道了lock.newConditio ...
java ReentrantLock Condition调试记录 -
smallbee:
brad2309 写道lz 你的两个messageReceiv ...
基于Apache Mina实现的TCP长连接和短连接实例 -
brad2309:
lz 你的两个messageReceived方法是不是错乱了
基于Apache Mina实现的TCP长连接和短连接实例
1、服务端:ServerSocketChannel进行监听,注册SelectionKey.OP_ACCEPT事件,服务器阻塞在selector.select()方法中,等待客户端连接。
2、客户端:SocketChannel创建连接,调用socketChannel.connect(SERVER_ADDRESS)连接服务器(此时服务器之前阻塞在selector.select()往下走,进入selectionKey.isAcceptable()逻辑,通过ServerSocketChannel的accept方法获得客户端SocketChannel,SocketChannel注册 SelectionKey.OP_READ事件,等待客户端输入流,此时又阻塞在selector.select()方法),客户端进入selectionKey.isConnectable(),如果client.isConnectionPending()==true,通过 client.finishConnect()强制连接,然后准备数据,通过client.write(sendbuffer)向服务器发送数据,此时,服务器之前阻塞在selector.select()往下走,进入selectionKey.isReadable()逻辑,通过缓冲区读取客户端输入流,然后调用client.register(selector, SelectionKey.OP_WRITE)注册写客户端流事件,进入selectionKey.isWritable()逻辑,准备写客户端的数据,通过client.write(sendbuffer)方法写给客户端,客户端之前write之后,会进行注册SelectionKey.OP_READ,等待服务器响应,阻塞在selector.select()中,由于这个时候服务器有了返回,就不阻塞了,进入selectionKey.isReadable()逻辑,得到服务器返回,如果需要再次发送数据给服务器,则注册write事件。刚才服务器write给客户端之后,如果想继续收到客户端数据,需要注册client.register(selector, SelectionKey.OP_READ)读事件,等待客户端再一次写入数据,阻塞在selector.select()方法
服务端:
package com.rb.socket.nio.server.n; 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.util.Iterator; import java.util.Set; public class NIOServer { /*标识数字*/ private int flag = 0; /*缓冲区大小*/ private int BLOCK = 4096; /*接受数据缓冲区*/ private ByteBuffer sendbuffer = ByteBuffer.allocate(BLOCK); /*发送数据缓冲区*/ private ByteBuffer receivebuffer = ByteBuffer.allocate(BLOCK); private Selector selector; public NIOServer(int port) throws IOException { // 打开服务器套接字通道 ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); // 服务器配置为非阻塞 serverSocketChannel.configureBlocking(false); // 检索与此通道关联的服务器套接字 ServerSocket serverSocket = serverSocketChannel.socket(); // 进行服务的绑定 serverSocket.bind(new InetSocketAddress(port)); // 通过open()方法找到Selector selector = Selector.open(); // 注册到selector,等待连接 serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); System.out.println("Server Start----:" + port); } // 监听 private void listen() throws IOException { while (true) { // 选择一组键,并且相应的通道已经打开 selector.select(); // 返回此选择器的已选择键集。 Set<SelectionKey> selectionKeys = selector.selectedKeys(); Iterator<SelectionKey> iterator = selectionKeys.iterator(); while (iterator.hasNext()) { SelectionKey selectionKey = iterator.next(); iterator.remove(); handleKey(selectionKey); } } } // 处理请求 private void handleKey(SelectionKey selectionKey) throws IOException { // 接受请求 ServerSocketChannel server = null; SocketChannel client = null; String receiveText; String sendText; int count = 0; // 测试此键的通道是否已准备好接受新的套接字连接。 if (selectionKey.isAcceptable()) { // 返回为之创建此键的通道。 server = (ServerSocketChannel) selectionKey.channel(); // 接受到此通道套接字的连接。 // 此方法返回的套接字通道(如果有)将处于阻塞模式。 client = server.accept(); // 配置为非阻塞 client.configureBlocking(false); // 注册到selector,等待连接 client.register(selector, SelectionKey.OP_READ); } else if (selectionKey.isReadable()) { // 返回为之创建此键的通道。 client = (SocketChannel) selectionKey.channel(); //将缓冲区清空以备下次读取 receivebuffer.clear(); //读取服务器发送来的数据到缓冲区中 count = client.read(receivebuffer); if (count > 0) { receiveText = new String(receivebuffer.array(), 0, count); System.out.println("服务器端接受客户端数据--:" + receiveText); client.register(selector, SelectionKey.OP_WRITE); } } else if (selectionKey.isWritable()) { //将缓冲区清空以备下次写入 sendbuffer.clear(); // 返回为之创建此键的通道。 client = (SocketChannel) selectionKey.channel(); sendText = "message from server--" + flag++; //向缓冲区中输入数据 sendbuffer.put(sendText.getBytes()); //将缓冲区各标志复位,因为向里面put了数据标志被改变要想从中读取数据发向服务器,就要复位 sendbuffer.flip(); //输出到通道 client.write(sendbuffer); System.out.println("服务器端向客户端发送数据--:" + sendText); client.register(selector, SelectionKey.OP_READ); } } /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { // TODO Auto-generated method stub int port = 8011; NIOServer server = new NIOServer(port); server.listen(); } }
客户端:
package com.rb.socket.nio.server.n; import java.io.IOException; 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.util.Iterator; import java.util.Set; public class NIOClient { /*标识数字*/ private static int flag = 0; /*缓冲区大小*/ private static int BLOCK = 4096; /*接受数据缓冲区*/ private static ByteBuffer sendbuffer = ByteBuffer.allocate(BLOCK); /*发送数据缓冲区*/ private static ByteBuffer receivebuffer = ByteBuffer.allocate(BLOCK); /*服务器端地址*/ private final static InetSocketAddress SERVER_ADDRESS = new InetSocketAddress( "localhost", 8011); public static void main(String[] args) throws IOException { // TODO Auto-generated method stub // 打开socket通道 SocketChannel socketChannel = SocketChannel.open(); // 设置为非阻塞方式 socketChannel.configureBlocking(false); // 打开选择器 Selector selector = Selector.open(); // 注册连接服务端socket动作 socketChannel.register(selector, SelectionKey.OP_CONNECT); // 连接 socketChannel.connect(SERVER_ADDRESS); // 分配缓冲区大小内存 Set<SelectionKey> selectionKeys; Iterator<SelectionKey> iterator; SelectionKey selectionKey; SocketChannel client; String receiveText; String sendText; int count=0; while (true) { //选择一组键,其相应的通道已为 I/O 操作准备就绪。 //此方法执行处于阻塞模式的选择操作。 selector.select(); //返回此选择器的已选择键集。 selectionKeys = selector.selectedKeys(); //System.out.println(selectionKeys.size()); iterator = selectionKeys.iterator(); while (iterator.hasNext()) { selectionKey = iterator.next(); if (selectionKey.isConnectable()) { System.out.println("client connect"); client = (SocketChannel) selectionKey.channel(); // 判断此通道上是否正在进行连接操作。 // 完成套接字通道的连接过程。 if (client.isConnectionPending()) { client.finishConnect(); System.out.println("完成连接!"); sendbuffer.clear(); sendbuffer.put("Hello,Server".getBytes()); sendbuffer.flip(); client.write(sendbuffer); } client.register(selector, SelectionKey.OP_READ); } else if (selectionKey.isReadable()) { client = (SocketChannel) selectionKey.channel(); //将缓冲区清空以备下次读取 receivebuffer.clear(); //读取服务器发送来的数据到缓冲区中 count=client.read(receivebuffer); if(count>0){ receiveText = new String( receivebuffer.array(),0,count); System.out.println("客户端接受服务器端数据--:"+receiveText); client.register(selector, SelectionKey.OP_WRITE); } } else if (selectionKey.isWritable()) { sendbuffer.clear(); client = (SocketChannel) selectionKey.channel(); sendText = "message from client--" + (flag++); sendbuffer.put(sendText.getBytes()); //将缓冲区各标志复位,因为向里面put了数据标志被改变要想从中读取数据发向服务器,就要复位 sendbuffer.flip(); client.write(sendbuffer); System.out.println("客户端向服务器端发送数据--:"+sendText); client.register(selector, SelectionKey.OP_READ); } } selectionKeys.clear(); } } }
发表评论
-
bike1
2015-12-07 17:10 0rt -
GPRS打印机的原理
2015-07-31 09:09 746一、什么是GPRS无线打印 ... -
关于 expression="execution(* com.xy.service.*.*(..))"
2015-05-21 09:22 2644先来看看这个spring的配 ... -
md5 sha1 java和javascript实现
2015-05-21 08:11 866<%@ page language="ja ... -
RSA帮助类
2014-11-21 09:36 911package com.cmb.fmserver.passp ... -
src2014-2-17
2014-02-17 21:55 0rt -
springmvc例子
2014-02-11 11:09 0rt -
qhdescjyw
2014-02-11 10:33 0rt -
按字节截取含有中文汉字的字符串
2013-05-07 18:55 3091要求实现一个按字节截取字符串的方法,比如对于字符串&quo ... -
SSL多线程安全问题
2013-04-23 15:44 1744项目原因,代码实现 ... -
wait notify 对象锁
2013-03-14 15:21 1151通常,多线程之间需要协调工作。例如,浏览器的一个显示图片的 ... -
eclipse下配置hadoop环境
2012-12-05 11:44 1404按照http://smallbee.iteye.com ... -
centos虚拟机上安装运行hadoop(伪分布)
2012-11-15 15:28 19481、先在确认能否不输入口令就用ssh登录localhost: ... -
nio 远程主机强迫关闭了一个现有的连接 解决方案
2012-10-17 12:37 4587nio编程过程中会出现: Exception in thre ... -
socket 客户端连接池实现
2012-10-15 16:58 6694本文参考:http://cache.baidu.com/c?m ... -
java dom 解析xml例子
2012-08-02 14:09 1549XML格式如下: <?xml version=&quo ... -
DM5 java 例子
2012-08-02 10:38 1234package com.cmb.fbcbcserver; ... -
HTTP短连接模拟长连接 连接数不能超过2个
2012-08-01 15:47 2021项目中有用到服务器推技术,也是由于环境因素,银行系统,行内机房 ... -
java注解使用例子
2012-07-30 11:50 11701、注解定义: import java.lang.annot ... -
SSL通俗易懂说法
2012-07-30 11:18 1163Bob,Alice和数字证书 网络安全中最知名的人物大概就是 ...
相关推荐
### Java NIO 处理超大数据文件的知识点详解 #### 一、Java NIO简介 Java NIO(New IO)是Java平台上的新输入/输出流API,它提供了与传统IO(即Java IO)不同的数据处理方式。NIO在Java 1.4版本引入,并在后续版本...
整个过程中,NIO通过非阻塞I/O避免了线程阻塞,提高了系统资源的利用率,尤其在处理大量并发连接时,其优势更为明显。 以上就是Java NIO的基本概念和工作流程,以及结合文件名推测的`NIOServer.java`和`NIOClient....
### Java NIO 实现Socket通信详解 #### 一、NIO与传统IO的区别及优势 在探讨如何使用Java NIO实现Socket通信之前,我们需要先理解NIO(Non-blocking I/O,非阻塞I/O)与传统阻塞I/O之间的区别。 **传统阻塞I/O...
在这个“基于java NIO的socket通信demo”中,我们将探讨如何使用NIO进行服务器和客户端的Socket通信,并解决通信过程中的字符集乱码问题。 首先,我们来看`NioServer.java`。这个文件中包含了一个基于NIO的服务器端...
Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java从1.4版本开始引入的一个新特性,旨在提供一...在学习过程中,你可以逐步深入,从基础的Buffer操作到复杂的Selector机制,掌握Java NIO的精髓。
Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java从1.4版本开始引入的一种新的I/O模型,相对于传统的BIO( Blocking I/O)模型,NIO在处理高并发、大数据量的网络应用时表现出更高的效率和...
### Java NIO 系列教程(一):Java NIO 概述 #### 一、引言 Java NIO(New IO)是Java SE 1.4版本引入的一个新的I/O处理框架,它...在未来的学习过程中,继续深入理解这些概念将有助于您更好地掌握Java NIO技术。
Java NIO(New IO)是Java 1.4引入的一个新特性,它是对传统IO模型的重大改进,提供了更高效的数据处理方式。NIO的核心概念包括通道(Channels)、缓冲区(Buffers)和选择器(Selectors)。它允许多个输入/输出操作...
在Java的传统IO模型中,一切操作都是基于流(Stream)的,无论是输入流还是输出流,它们都是顺序读写的,且在读写过程中会阻塞线程,直到读写完成。例如,`FileInputStream`和`FileOutputStream`就是典型的阻塞IO流...
Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java从1.4版本开始引入的一种I/O模型,旨在提供一种更高效、更具弹性的I/O处理方式。相比于传统的BIO( Blocking I/O)模型,NIO在处理高并发和大...
Java NIO(Non-blocking Input/Output)是一种在Java中处理I/O操作的新方式,相比于传统的BIO(Blocking I/O),NIO提供了更高效的数据传输能力,尤其适合于高并发、低延迟的网络应用,如聊天服务器。在这个场景下,...
### Java NIO原理 图文分析及代码实现 #### 前言 在深入探讨Java NIO之前,我们先简要回顾一下NIO的概念及其引入的原因。随着互联网的发展,越来越多的应用程序需要处理高并发的网络连接请求。传统的阻塞I/O模型在...
Java IO模型是一种阻塞型I/O模型,在数据的读写过程中,如果线程在等待数据,将会一直被挂起。当数据准备就绪后,线程会从阻塞状态恢复并继续执行。这种模型在处理小量级并发连接时表现尚可,但在面对高并发场景时,...
本文将着重探讨电信业务应用软件的发展历程和技术变迁,特别是Java NIO框架在这一过程中所扮演的重要角色。 **1.2 华为电信软件的技术演进史** ##### 1.2.1 C和C++主导的第一代架构 在2005年以前,华为电信软件的...
Java NIO(New Input/Output)是Java标准库提供的一种I/O模型,它与传统的 Blocking I/O(阻塞式I/O)有所不同。在传统的IO模型中,读写操作会阻塞线程,直到数据准备好或者写入完成。而NIO则引入了非阻塞模式,使得...
### Java IO 与 Java NIO 的区别 在深入探讨Java IO与Java NIO之间的区别之前,我们先简单回顾一下这两种I/O模型的基本概念。 #### 1. Java IO(Blocking IO) Java IO,也称为传统的阻塞式IO或同步阻塞式IO,是...
Java NIO,全称为Non-blocking Input/Output,是Java在1.4版本引入的一个新特性,旨在提供一种更高效、更灵活的I/O操作方式。相比于传统的BIO(Blocking I/O),NIO允许我们以非阻塞的方式读写数据,提高了系统资源...
Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java标准库提供的一种替代传统I/O模型的新技术。尚硅谷的12讲Java NIO课程,旨在深入浅出地讲解这一重要概念,帮助开发者提升程序的性能和效率。...
Java NIO(New Input/Output)是Java提供的一种新的输入输出处理机制,它与传统IO基于流的处理方式不同,NIO支持面向缓冲区的(Buffer-oriented)、基于通道的(Channel-based)I/O操作。在Java NIO中,Buffer类是...