使用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();

你可能感兴趣的:(nio)