AIO理解起来有点绕,本人也懒得用,这都是小demo,了解下概念和流程就可以了,实际应用是不会这么用的,因为多次读写都可能会导致粘包,不完全度等等一系列的问题。
Client:
package 网络编程_AIO;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
public class Client implements Runnable {
private AsynchronousSocketChannel channel = null;
public Client() throws Exception {
channel = AsynchronousSocketChannel.open();
}
public void connect() {
channel.connect(new InetSocketAddress("127.0.0.1", 8888));
}
public void wirte(String request) {
try {
channel.write(ByteBuffer.wrap(request.getBytes())).get();
read();
} catch (Exception e) {
e.printStackTrace();
}
}
private void read() {
ByteBuffer readBuffer = ByteBuffer.allocate(1024);
try {
channel.read(readBuffer).get();
readBuffer.flip();
byte[] bys = new byte[readBuffer.remaining()];
readBuffer.get(bys);
System.out.println(new String(bys, "utf-8").trim());
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void run() {
while (true) {
}
}
public static void main(String[] args) throws Exception {
Client c1 = new Client();
Client c2 = new Client();
Client c3 = new Client();
c1.connect();
c2.connect();
c3.connect();
new Thread(c1,"c1").start();
new Thread(c2,"c2").start();
new Thread(c3,"c3").start();
Thread.sleep(1000);
c1.wirte("c1 say hello");
c2.wirte("c2 say fuck");
c3.wirte("c3 say good afternoon");
}
}
server:
package 网络编程_AIO;
import java.net.InetSocketAddress;
import java.nio.channels.AsynchronousChannelGroup;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Server {
private ExecutorService executorService;
private AsynchronousChannelGroup group;
public AsynchronousServerSocketChannel socketChannel;
public Server(int port){
try {
executorService = Executors.newCachedThreadPool();
group = AsynchronousChannelGroup.withCachedThreadPool(executorService, 1);
socketChannel = AsynchronousServerSocketChannel.open(group);
socketChannel.bind(new InetSocketAddress(port));
socketChannel.accept(this,new ServerCompeletionHandler());
Thread.sleep(Integer.MAX_VALUE);
} catch (Exception e) {
e.printStackTrace();
}
}
@SuppressWarnings("unused")
public static void main(String[] args) {
Server server = new Server(8888);
}
}
ServerCompletionHandler:
package 网络编程_AIO;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
public class ServerCompeletionHandler implements CompletionHandler<AsynchronousSocketChannel,Server>{
@Override
public void completed(AsynchronousSocketChannel result, Server attachment) {
attachment.socketChannel.accept(attachment,this);
read(result);
}
private void read(AsynchronousSocketChannel result) {
ByteBuffer buffer = ByteBuffer.allocate(1024);
result.read(buffer,buffer,new CompletionHandler<Integer,ByteBuffer>() {
@Override
public void completed(Integer resultSize, ByteBuffer attachment) {
attachment.flip();
System.out.println("Server:接受的到的客户端长度为"+resultSize);
String resultData = new String(attachment.array()).trim();
System.out.println("Server:接收到的客户端数据为:"+resultData);
String response = new String("服务端响应,接收到客户端数据为:"+resultData);
write(result,response);
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
exc.printStackTrace();
}
});
}
protected void write(AsynchronousSocketChannel result, String response) {
try {
ByteBuffer wirteBuffer = ByteBuffer.allocate(1024);
wirteBuffer.put(response.getBytes());
wirteBuffer.flip();
result.write(wirteBuffer).get();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void failed(Throwable exc, Server attachment) {
exc.printStackTrace();
}
}
输出结果:
client:
服务端响应,接收到客户端数据为:c1 say hello
服务端响应,接收到客户端数据为:c2 say fuck
服务端响应,接收到客户端数据为:c3 say good afternoon
server:
Server:接受的到的客户端长度为12
Server:接收到的客户端数据为:c1 say hello
Server:接受的到的客户端长度为11
Server:接收到的客户端数据为:c2 say fuck
Server:接受的到的客户端长度为21
Server:接收到的客户端数据为:c3 say good afternoon
AIO是JDK1.7之后提供的异步非阻塞网络通信,个人觉得还是麻烦,不好用,以后会提供更好的方式,框架Netty.