标签: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