`

[java]NIO SocketChannel read使用说明

 
阅读更多

这篇文章只是说说简单的使用,内容不难,很简单很基础。

如果说错了希望纠正。

最近在做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();
		}
	}

 

 

0
1
分享到:
评论

相关推荐

    java NIO实例

    在`NIOClient.java`文件中,可能会创建SocketChannel连接服务器,然后设置非阻塞模式,通过read()或write()方法进行数据交换。同时,客户端也需要配置一个Selector来监控通道状态。 在`NIOServer.java`中,服务器端...

    一个java NIO的例子

    本例子中的"NioServer"可能是一个简单的Java NIO服务器端程序,用于演示如何使用NIO进行网络通信。下面我们将深入探讨Java NIO的关键组件和工作原理。 1. **通道(Channel)**:通道是数据传输的途径,类似于传统的...

    java NIO原理和使用

    ### Java NIO 原理与使用详解 #### 一、Java NIO 概述 在深入了解 Java NIO 的工作原理及其使用之前,我们首先来了解一下什么是 Java NIO(New I/O)。Java NIO 是 Java SE 1.4 版本引入的一个全新的 I/O API,...

    java nio 实现socket

    在探讨如何使用Java NIO实现Socket通信之前,我们需要先理解NIO(Non-blocking I/O,非阻塞I/O)与传统阻塞I/O之间的区别。 **传统阻塞I/O模型**:在传统的Java IO编程中,当我们调用`read()`或`write()`方法时,...

    Java NIO Socket基本

    4. **管道(Pipe)**:在某些特定情况下,两个线程之间可以使用`java.nio.Pipe`进行单向数据传递。 5. **文件系统API**:NIO还提供了`java.nio.file`包,包含一系列与文件系统交互的类,如Files、Paths等。 Java ...

    java NIO详细教程

    ### Java NIO 详细教程知识点解析 #### 一、Java NIO 概述 Java NIO(New IO)是Java平台提供的一种新的IO操作模式,它首次出现在Java 1.4版本中,并在后续版本中不断完善。Java NIO 的设计目的是为了克服传统Java ...

    JAVA nio的一个简单的例子

    在这个“JAVA nio的一个简单的例子”中,我们将探讨如何使用Java NIO进行简单的服务器-客户端通信,并计算字符串的哈希值。 在传统的BIO模型中,每个连接都需要一个线程来处理,当并发连接数量增加时,系统会创建...

    java NIO推送实例

    在这个实例中,"java NIO 消息推送实例" 旨在展示如何使用NIO进行服务器向客户端的消息推送。 1. **Java NIO基础** - **通道(Channels)**:Java NIO 提供了多种通道,如文件通道、套接字通道等,它们代表不同...

    java的ServerSocketChannel与SocketChannel的使用

    Java的`ServerSocketChannel`和`SocketChannel`是NIO(非阻塞I/O)框架中的核心组件,它们为创建高性能、高并发的网络服务提供了基础。在Java中,传统的I/O模型基于流(Stream),而NIO则引入了通道(Channel)和...

    JAVA NIO 异步通信客户端

    在描述中提到的"JAVA NIO 异步通信客户端"是指使用NIO API实现的一个客户端程序,它能够在不阻塞主线程的情况下进行网络通信。这通常通过使用Selector和Channel来完成。Selector负责监控多个通道的状态变化,而...

    JavaNIO.pdf

    Java NIO中提供了多种类型的通道,如ByteChannel、GatheringByteChannel、InterruptibleChannel、ReadableByteChannel、ScatteringByteChannel、WritableByteChannel、DatagramChannel、FileChannel、...

    java SocketChannel通信实例

    本实例着重讲解如何利用Java NIO(Non-blocking Input/Output,非阻塞输入/输出)中的SocketChannel进行非阻塞通信。 非阻塞通信是一种高效的数据传输方式,它允许线程在等待数据时不会被挂起,而是可以执行其他...

    java nio Selector的使用-客户端

    本篇文章将深入探讨如何在Java NIO中使用Selector处理客户端的I/O请求。 首先,我们需要理解Selector的工作原理。Selector是一个多路复用器,它可以监控多个通道的事件状态,如连接就绪、数据可读或可写等。通过...

    Java NIO原理 图文分析及代码实现

    为了更好地理解Java NIO的使用方式,下面我们通过简单的代码示例来展示如何实现一个基本的NIO服务端和客户端。 **服务端代码实现** ```java package cn.nio; import java.io.IOException; import java.net....

    java nio 入门

    在本文中,我们将深入探讨Java NIO的基本概念、组件以及如何在实际编程中使用。 一、Java NIO概述 Java NIO并非简单的输入输出API的替代,而是提供了一种新的I/O模型。传统IO基于流(Stream)进行数据读写,而NIO基于...

    java nio服务器

    标题中的“java nio服务器”指的是使用Java NIO API构建的网络服务器,这种服务器设计模式通常被称为多路复用或非阻塞I/O服务器。NIO的核心组件包括通道(Channels)、缓冲区(Buffers)和选择器(Selectors)。下面...

    java nio 聊天室源码

    在这个“java nio 聊天室源码”项目中,开发者使用了NIO来构建一个聊天室应用,以实现用户之间的实时通信。 1. **Java NIO基础** - **通道(Channel)**:在NIO中,数据是通过通道进行传输的,如SocketChannel、...

    JavaNIO.zip_java nio_nio java

    下面是一些关键的Java NIO使用示例: 1. **读取文件**:使用FileChannel从文件中读取数据到缓冲区,然后从缓冲区获取数据。 ```java FileInputStream fis = new FileInputStream("file.txt"); FileChannel channel ...

Global site tag (gtag.js) - Google Analytics