码迷,mamicode.com
首页 > 编程语言 > 详细

Java NIO (一)

时间:2015-10-29 13:37:47      阅读:241      评论:0      收藏:0      [点我收藏+]

标签:java nio

  具备非阻塞、信道复用等特性的JAVA NIO极大地提高了TCP通信的效率,由于JAVA NIO具有非阻塞的特性,所以基于这一特性可以使用一个线管理多个链接。下面的程序演示了在不使用Selector的情况下简单模拟了一个TCP服务器的搭建和客户端的访问:

1,服务器类Server.java

package com.zws.nio.nosel;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;

import com.zws.nio.util.NIOHelper;

public class Server extends Thread{
	
	private ServerSocketChannel sevChn = null;
	private SocketChannel chn = null;
	private boolean block = false;
	private int port;
	
	public Server(int port) {
		this.port = port;
		init();
	}

	@Override
	public void run() {
		while (!isInterrupted()) {
			try {
				//此处的accept方法是一个非阻塞的方法,即不管有没有客户端链接都会返回,在没有客户端链接的情况下返回null。
				if ((chn = sevChn.accept()) != null) {
					String msg = NIOHelper.read(chn);
					System.out.println("Server gets msg:" + msg);
					
					msg = "Hello Client...";
					NIOHelper.write(chn, msg);
					chn.close();
				} else {
					//do something else
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	/*
	 * 初始化ServerSocketChannel、SocketChannel
	 */
	private void init() {
		try {
			sevChn = ServerSocketChannel.open();
			sevChn.configureBlocking(block);//配置阻塞,false:非阻塞,true:阻塞
			sevChn.socket().bind(new InetSocketAddress(port));
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}
	/**
	 * 关闭服务器
	 */
	public void close() {
		this.interrupt();
		if (sevChn != null)
			try {
				sevChn.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
	}

	public static void main(String[] args) {
		Server server = new Server(9003);
		server.start();
		//server.close();
	}
}

2,客户端类:Client.java

package com.zws.nio.nosel;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SocketChannel;

import com.zws.nio.util.NIOHelper;

public class Client {

	public static void main(String[] args) {
		boolean block = false;
		SocketChannel chn = null;
		try {
			chn = SocketChannel.open();
			chn.connect(new InetSocketAddress("localhost", 9003));
			chn.configureBlocking(block);
			while (true) {
				//是否完成链接,非阻塞方法。
				if (chn.finishConnect()) {
					String msg = "Hello Server...";
					NIOHelper.write(chn, msg);
					
					msg = NIOHelper.read(chn);
					System.out.println("Client gets msg:" + msg);
					break;
				} else {
					//do something else
				}
			}
			
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (chn != null)
				try {
					chn.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
		}
	}
}

3,辅助类:NIOHelper.java

package com.zws.nio.util;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;

public class NIOHelper {
	public static final String CHARSET_UTF8 = "UTF-8";

	public static void write(SocketChannel chn, String msg) throws IOException {
		
		byte[] bts = msg.getBytes(CHARSET_UTF8);
		int len = bts.length;
		ByteBuffer buffer = ByteBuffer.allocate(len + 4);
		buffer.put(IntegerUtil.toBytes(len));//前4个字节为报文长度
		buffer.put(bts);
		buffer.flip();
		while (buffer.hasRemaining())
			chn.write(buffer);
	}
	
	public static String read(SocketChannel chn) throws IOException {
		String msg = null;
		byte[] bts = new byte[4];
		ByteBuffer buffer = ByteBuffer.allocate(4);
		while (chn.read(buffer) == 0) {}
		buffer.flip();
		buffer.get(bts, 0, buffer.remaining());
		
		int size = IntegerUtil.toInt(bts);
		buffer = ByteBuffer.allocate(size);
		while (chn.read(buffer) == 0) {}
		buffer.flip();
		bts = new byte[size];
		buffer.get(bts, 0, buffer.remaining());
		msg = new String(bts,CHARSET_UTF8);
		return msg;
	}
}

4,辅助类:IntegerUtil.java

package com.zws.nio.util;

public class IntegerUtil {

	/**
	 * 将int转化成4字节数组
	 * @param value
	 * @return
	 */
	public static byte[] toBytes(int value) {
	    byte[] bytes = new byte[4];
	    for (int i = 0; i < 4; i++) {
	        bytes[i] = (byte) (value >> 8 * i & 0xFF);
	    }
	    return bytes;
	}
	/**
	 * 字节数组转化int
	 * @param bytes
	 * @return
	 */
	public static int toInt(byte[] bytes) {
	    int value = 0;

	    for (int i = 0; i < bytes.length; i++) {
	        byte item = bytes[i];
	        value += (item & 0xFF) << (8 * i);
	    }
	    return value;
	}
}

本文出自 “埃文” 博客,请务必保留此出处http://wenshengzhu.blog.51cto.com/5151285/1707510

Java NIO (一)

标签:java nio

原文地址:http://wenshengzhu.blog.51cto.com/5151285/1707510

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!