使用NIO处理对象数据

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();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值