标签: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
原文地址:http://wenshengzhu.blog.51cto.com/5151285/1707510