这篇文章只是说说简单的使用,内容不难,很简单很基础。
如果说错了希望纠正。
最近在做NIO的服务器端和客服端开发(虽然有mina 但是自己从头写感觉会好一点 当做练习的话)
SocketChannel有两种模式:blocking模式(和原来的Socket类似)和non-blocking模式(不会堵塞)
在两种模式下的读写操作是不一样的。 写比较好理解,非堵塞下可能会一个字节都不写(缓存区满了 堵塞的这种情况就是堵塞在那了)
在非堵塞模式下只要用while判断一下ByteBuffer的remaining就可以了:
public void write(ByteBuffer byteBuffer) throws IOException { byteBuffer.flip(); while(byteBuffer.hasRemaining()){ sc.write(byteBuffer); } }
接下来说说read read的返回参数有三个
正整数 0和-1
正整数在堵塞和非堵塞模式中意义是一样的,就是读入了多少个字节。
0的话涵义不同:
- 在堵塞中,如果返回0就说明服务器发送了请求但请求内容为空.
- 在非堵塞模式中,如果在read的时候流中暂时还没内容那么返回的也是0(堵塞中没有内容就堵塞在那了).
-1都表示连接已经断开(单向的连接 比如用shutdonwInput把Input流断开了 read就返回-1 但直接close的话 会返回一个java.nio.channels.ClosedChannelException的异常
有几个实验来证明以上的 实验都是连接www.baidu.com 百度现在用的最多的就是编程中测试了....
// 阻塞模式下 没有发送请求就read 会一直堵在read方法里 @Test public void testSocketChannel(){ InetSocketAddress address=new InetSocketAddress("www.baidu.com",80); try { SocketChannel sc=SocketChannel.open(address); ByteBuffer bb=ByteBuffer.allocate(1024); //sc.configureBlocking(false); System.out.println(sc.read(bb)); } catch (IOException e) { e.printStackTrace(); } }
然后把注释去掉设置成非阻塞模式,就可见读回了0.
然后是-1的返回情况:
//阻塞和非阻塞一样 这都会返回-1 因为通道已经断了(end-of-stream的意思应该理解成断开比较好吧) @Test public void testSocketChannel(){ InetSocketAddress address=new InetSocketAddress("www.baidu.com",80); try { SocketChannel sc=SocketChannel.open(address); ByteBuffer bb=ByteBuffer.allocate(1024); sc.configureBlocking(false); sc.shutdownInput(); System.out.println(sc.read(bb)); } catch (IOException e) { e.printStackTrace(); } }
好接下去的实验就让他接受百度返回的回应:
为了看得清楚就写成死循环不断读了,堵塞的情况:
@Test public void testSocketChannel2(){ InetSocketAddress address=new InetSocketAddress("www.baidu.com",80); try { SocketChannel sc=SocketChannel.open(address); Charset charset=Charset.forName("UTF-8"); ByteBuffer bb=ByteBuffer.allocate(1024); String send="GET / HTTP/1.1\r\n\r\n"; //sc.configureBlocking(false); sc.write(charset.encode(send)); while(true){ bb.clear(); System.out.println(sc.read(bb)); bb.flip(); System.out.println(charset.decode(bb).toString()); } } catch (IOException e) { e.printStackTrace(); } }
输出完后就一直卡在read里了 返回内容太长我就不打出来了
然后把注释去掉变为非阻塞的话,接下去除了输出完内容外就是不断地打0了
这里也说明不管用堵塞模式和非堵塞模式 用 read()!=-1来判断一次请求已经读完是多么不靠谱 堵塞模式会堵塞还好 非堵塞模式用0来判断还是不错的 这边实验性地写一下有关非堵塞模式完整读完一次请求的(当然只是试验性写一下 正常使用结合Selector写不用担心我这边试验代码的一些问题):
@Test public void testSocketChannel2(){ InetSocketAddress address=new InetSocketAddress("www.baidu.com",80); try { SocketChannel sc=SocketChannel.open(address); Charset charset=Charset.forName("UTF-8"); ByteBuffer bb=ByteBuffer.allocate(1024); String send="GET / HTTP/1.1\r\n\r\n"; sc.configureBlocking(false); sc.write(charset.encode(send)); try { Thread.sleep(5000); //给予足够的时间让服务器返回信息 不然下面直接返回0 } catch (InterruptedException e) { e.printStackTrace(); } //0 -->如果没有信息读入 或者已经把信息读完了 //-1-->输入的channel已经关闭了 while(sc.read(bb)>0){ if(bb.remaining()<bb.capacity()*0.02){ ByteBuffer nbb=ByteBuffer.allocate(bb.capacity()*2); bb.flip(); nbb.put(bb); bb=nbb; System.out.println(bb.capacity()); } } bb.flip(); System.out.println(charset.decode(bb).toString()); } catch (IOException e) { e.printStackTrace(); } }
相关推荐
在`NIOClient.java`文件中,可能会创建SocketChannel连接服务器,然后设置非阻塞模式,通过read()或write()方法进行数据交换。同时,客户端也需要配置一个Selector来监控通道状态。 在`NIOServer.java`中,服务器端...
本例子中的"NioServer"可能是一个简单的Java NIO服务器端程序,用于演示如何使用NIO进行网络通信。下面我们将深入探讨Java NIO的关键组件和工作原理。 1. **通道(Channel)**:通道是数据传输的途径,类似于传统的...
### Java NIO 原理与使用详解 #### 一、Java NIO 概述 在深入了解 Java NIO 的工作原理及其使用之前,我们首先来了解一下什么是 Java NIO(New I/O)。Java NIO 是 Java SE 1.4 版本引入的一个全新的 I/O API,...
在探讨如何使用Java NIO实现Socket通信之前,我们需要先理解NIO(Non-blocking I/O,非阻塞I/O)与传统阻塞I/O之间的区别。 **传统阻塞I/O模型**:在传统的Java IO编程中,当我们调用`read()`或`write()`方法时,...
4. **管道(Pipe)**:在某些特定情况下,两个线程之间可以使用`java.nio.Pipe`进行单向数据传递。 5. **文件系统API**:NIO还提供了`java.nio.file`包,包含一系列与文件系统交互的类,如Files、Paths等。 Java ...
### Java NIO 详细教程知识点解析 #### 一、Java NIO 概述 Java NIO(New IO)是Java平台提供的一种新的IO操作模式,它首次出现在Java 1.4版本中,并在后续版本中不断完善。Java NIO 的设计目的是为了克服传统Java ...
在这个“JAVA nio的一个简单的例子”中,我们将探讨如何使用Java NIO进行简单的服务器-客户端通信,并计算字符串的哈希值。 在传统的BIO模型中,每个连接都需要一个线程来处理,当并发连接数量增加时,系统会创建...
在这个实例中,"java NIO 消息推送实例" 旨在展示如何使用NIO进行服务器向客户端的消息推送。 1. **Java NIO基础** - **通道(Channels)**:Java NIO 提供了多种通道,如文件通道、套接字通道等,它们代表不同...
Java的`ServerSocketChannel`和`SocketChannel`是NIO(非阻塞I/O)框架中的核心组件,它们为创建高性能、高并发的网络服务提供了基础。在Java中,传统的I/O模型基于流(Stream),而NIO则引入了通道(Channel)和...
在描述中提到的"JAVA NIO 异步通信客户端"是指使用NIO API实现的一个客户端程序,它能够在不阻塞主线程的情况下进行网络通信。这通常通过使用Selector和Channel来完成。Selector负责监控多个通道的状态变化,而...
Java NIO中提供了多种类型的通道,如ByteChannel、GatheringByteChannel、InterruptibleChannel、ReadableByteChannel、ScatteringByteChannel、WritableByteChannel、DatagramChannel、FileChannel、...
本实例着重讲解如何利用Java NIO(Non-blocking Input/Output,非阻塞输入/输出)中的SocketChannel进行非阻塞通信。 非阻塞通信是一种高效的数据传输方式,它允许线程在等待数据时不会被挂起,而是可以执行其他...
本篇文章将深入探讨如何在Java NIO中使用Selector处理客户端的I/O请求。 首先,我们需要理解Selector的工作原理。Selector是一个多路复用器,它可以监控多个通道的事件状态,如连接就绪、数据可读或可写等。通过...
为了更好地理解Java NIO的使用方式,下面我们通过简单的代码示例来展示如何实现一个基本的NIO服务端和客户端。 **服务端代码实现** ```java package cn.nio; import java.io.IOException; import java.net....
在本文中,我们将深入探讨Java NIO的基本概念、组件以及如何在实际编程中使用。 一、Java NIO概述 Java NIO并非简单的输入输出API的替代,而是提供了一种新的I/O模型。传统IO基于流(Stream)进行数据读写,而NIO基于...
标题中的“java nio服务器”指的是使用Java NIO API构建的网络服务器,这种服务器设计模式通常被称为多路复用或非阻塞I/O服务器。NIO的核心组件包括通道(Channels)、缓冲区(Buffers)和选择器(Selectors)。下面...
在这个“java nio 聊天室源码”项目中,开发者使用了NIO来构建一个聊天室应用,以实现用户之间的实时通信。 1. **Java NIO基础** - **通道(Channel)**:在NIO中,数据是通过通道进行传输的,如SocketChannel、...
下面是一些关键的Java NIO使用示例: 1. **读取文件**:使用FileChannel从文件中读取数据到缓冲区,然后从缓冲区获取数据。 ```java FileInputStream fis = new FileInputStream("file.txt"); FileChannel channel ...