JavaSE中基于Socket的网络通信是阻塞式的,当程序执行输入输出操作后,在这些操作返回之前会一直阻塞该线程,使得服务器要为每一个客户端提供线程进行数据处理,这种处理不适合处理数量多的客户端,jdk1.4后Java引入了nio.
在进行网络编程时,使用SocketChannel大大减轻了服务器的负担,在此贴上如何讲一个对象装入ByteBuffer的:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.ByteBuffer;
public class BStream {
public static ByteBuffer toByteBuffer(Object object) {
ByteArrayOutputStream bio = new ByteArrayOutputStream();
ObjectOutputStream oos = null;
ByteBuffer outBuf = null;
try {
//包装字节流
oos = new ObjectOutputStream(bio);
//将对象写入字节流
oos.writeObject(object);
//得到对象字节
byte[] ba = bio.toByteArray();
//得到对象字节的长度
int len = ba.length;
//字节缓冲区的大小为INT + 对象字节的长度
outBuf = ByteBuffer.allocate((Integer.SIZE >> 3) + len);
//压入数据:数据长度
outBuf.putInt(len);
//压入数据:对象数据
outBuf.put(ba);
//归位
outBuf.flip();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bio != null)
bio.close();
if (oos != null)
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return outBuf;
}
public static Object toObject(byte[] buff) {
ByteArrayInputStream bis = new ByteArrayInputStream(buff);
ObjectInputStream ois = null;
try {
//包装字节数组流
ois = new ObjectInputStream(bis);
} catch (IOException e) {
e.printStackTrace();
}
Object object = null;
try {
//读入对象
object = ois.readObject();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
try {
if (bis != null)
bis.close();
if (ois != null)
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return object;
}
}
数据包解析(部分代码):
System.out.println("client message");
//获取客户端通信的SocketChannel
SocketChannel sc = (SocketChannel) sk.channel();
// new ServiceThread(sc).start();
byte[] data = null;
try {
ByteBuffer lenbuff = ByteBuffer.allocate(4);
//读入对象数据的大小
sc.read(lenbuff);
lenbuff.flip();
int len = lenbuff.getInt();
if(len == 0) {
return;
}
//分配ByteBuffer的大小
ByteBuffer buff = ByteBuffer.allocate(len);
//一次性读取所有数据
sc.read(buff);
buff.flip();
data = buff.array();
sk.interestOps(SelectionKey.OP_READ);
} catch (IOException e) {
if(sk.channel() != null) {
sk.channel().close();
}
// e.printStackTrace();
}
//转成请求的对象
Request request = (Request) BStream.toObject(data);
String action = request.getAction();
分享到:
相关推荐
### Java NIO 处理超大数据文件的知识点详解 ...综上所述,使用Java NIO处理超大数据文件时,关键是利用好内存映射文件技术和合理的数据读取策略,通过适当的分块和数据解析方法,可以有效地提升读取速度和处理能力。
- 使用NIO的主要优势在于其非阻塞和内存映射特性,可以在处理大数据和高并发场景时提高效率。通过映射文件到内存,`MappedByteBuffer`可以避免频繁的磁盘I/O操作,从而提高读取速度。 5. **局限性与注意事项**: ...
总结来说,这个压缩包的内容可能涵盖了如何在Java NIO中实例化和使用通道、缓冲区、选择器,以及如何实现一个简单的多线程服务器,利用选择器来监听和处理来自多个客户端的非阻塞I/O请求。这些内容对于理解和使用...
2. **缓冲区(Buffer)**:在NIO中,数据被存储在缓冲区对象中。缓冲区提供了一种高效的方式管理内存,可以方便地进行读写操作。缓冲区有固定大小,一旦写满,需要清空或者翻转才能继续写入。同样,读取数据也需要将...
4. **内存映射文件**:NIO 支持将文件直接映射到内存中,这在处理大数据量时特别有用,因为它避免了多次数据复制。 #### 二、Java NIO 的核心组件 Java NIO 的核心组件主要包括 Channel 和 Buffer。 ##### 1. ...
在Java的IO编程中,NIO(Non-blocking Input/Output,非阻塞输入输出)是一种高效的数据处理方式,尤其适用于高并发场景。本示例主要关注如何使用NIO解决“沾包”问题以及处理因缓冲区满导致的写入失败问题。首先,...
- **垃圾产生多**:使用`BufferedReader`等类时,每次读取数据都会产生临时对象,这不仅增加了垃圾回收的压力,还可能引起性能瓶颈。 #### 3. NIO模型简介 为了解决上述问题,Java推出了NIO框架,其核心特性包括: ...
2. **缓冲区(Buffer)**:缓冲区是NIO中数据存储的主要对象,它是内存块的抽象,用于在通道和应用程序之间传输数据。Java NIO提供了多种类型的缓冲区,如ByteBuffer、CharBuffer、IntBuffer、FloatBuffer等,每种...
在Java编程领域,NIO(New IO)是一种用于处理I/O操作的非阻塞I/O模型,相较于传统的IO,NIO提供了更高效的数据传输方式。本篇将详细讲解如何使用NIO实现邮件接收,主要涉及JavaMail API和NIO的核心概念。 首先,...
NIO(New Input/Output)是Java平台上的一个库,提供了更高效的数据I/O操作方式,对比传统的IO模型,NIO更适合处理大量并发连接的情况。 MongoDB的开发涉及到多个方面,包括数据模型设计、查询优化、数据备份与恢复...
传统的IO模型是基于流的,通常涉及阻塞式读写,而NIO则引入了通道(Channels)和缓冲区(Buffers)的概念,并支持非阻塞I/O,这使得Java在处理高并发、大流量的网络应用时表现出更高的效率。 Groovy是一种动态类型...
Java IO主要包括了字节流(处理原始字节数据)和字符流(处理Unicode字符序列),以及用于文件、网络和对象的输入输出流。例如,FileInputStream和FileOutputStream用于文件操作,BufferedReader和PrintWriter用于...
Java NIO(New IO)是Java SE 1.4版本引入的一个新的I/O处理框架,它提供了比传统Java IO包更高效的数据处理方式。NIO的核心在于其三大组件:Channels、Buffers和Selectors。本文将详细介绍这三个组件的基础概念及其...
Java NIO(New IO)是Java 1.4版本引入的一个新模块,它提供了一种新的方式来处理I/O操作,相比传统的IO流,NIO提供了更高效、更灵活的数据读写方式。在这个主题中,我们将深入探讨Java NIO如何用于写文件,特别是在...
Java NIO(New IO)是Java 1.4引入的一个新特性,它是对传统IO模型的重大改进,提供了更高效的数据处理方式。NIO的核心概念包括通道(Channels)、缓冲区(Buffers)和选择器(Selectors)。它允许多个输入/输出操作...
在探讨如何使用Java NIO实现Socket通信之前,我们需要先理解NIO(Non-blocking I/O,非阻塞I/O)与传统阻塞I/O之间的区别。 **传统阻塞I/O模型**:在传统的Java IO编程中,当我们调用`read()`或`write()`方法时,...