传统BIO编程
服务端:
public class TimeServer {
public static void main(String[] args) throws IOException {
int port=8000;
if (args!=null && args.length>0){
try {
port=Integer.parseInt(args[0]);
}catch (NumberFormatException e){
}
}
ServerSocket serverSocket=null;
try {
serverSocket=new ServerSocket(port);
System.out.println("time server 启动端口:"+port);
Socket socket=null;
while (true){
socket=serverSocket.accept();
new Thread(new TimeServerHandler(socket)).start();
}
} catch (IOException e) {
e.printStackTrace();
}finally {
if (serverSocket!=null){
System.out.println("time server 关闭");
serverSocket.close();
serverSocket=null;
}
}
}
}
public class TimeServerHandler implements Runnable {
private Socket socket;
public TimeServerHandler(Socket socket) {
this.socket=socket;
}
@Override
public void run() {
BufferedReader in=null;
PrintWriter out=null;
try {
in=new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
out=new PrintWriter(this.socket.getOutputStream(),true);
String currentTime=null;
String body=null;
while (true){
body=in.readLine();
if (body==null){
break;
}
System.out.println("time server 接收顺序:"+body);
currentTime ="QUERY TIME ORDER".equalsIgnoreCase(body)?new Date(System.currentTimeMillis()).toString():"BAD ORDER";
out.println(currentTime);
}
} catch (IOException e) {
if (in!=null){
try {
in.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
if (out!=null){
out.close();
out=null;
}
if (this.socket!=null){
try {
this.socket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
this.socket=null;
}
}
}
客户端:
public class TimeClient {
public static void main(String[] args) {
int port=8000;
if (args!=null && args.length>0){
try {
port=Integer.parseInt(args[0]);
}catch (NumberFormatException e){
}
}
Socket socket=null;
BufferedReader in=null;
PrintWriter pw=null;
try {
socket = new Socket("127.0.0.1",port);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
pw = new PrintWriter(socket.getOutputStream(),true);
pw.println("QUERY TIME ORDER");
System.out.println("send order to server succed.");
String resp = in.readLine();
System.out.println("现在是:"+resp);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (pw!=null){
pw.close();
}
if (in!=null){
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket!=null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
socket=null;
}
}
}
伪异步IO
服务端:
public class TimeServer {
public static void main(String[] args) {
int port=8000;
if (args!=null && args.length>0){
try {
port=Integer.parseInt(args[0]);
}catch (NumberFormatException e){
}
}
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(port);
System.out.println("time server 启动,端口:" + port);
Socket socket = null;
while (true) {
socket = serverSocket.accept();
TimeserverHandlerExecutePool sigleExecutor= new TimeserverHandlerExecutePool(50,10000);
sigleExecutor.execute(new TimeServerHandler(socket));
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class TimeserverHandlerExecutePool{
private ExecutorService executor;
public TimeserverHandlerExecutePool(int maxPoolSize, int queueSize) {
executor = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),
maxPoolSize,120L, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(queueSize));
}
public void execute(Runnable task){
executor.execute(task);
}
}
客户端随意
NIO编程
服务端:
public class TimeserverHandlerExecutePool{
private ExecutorService executor;
public TimeserverHandlerExecutePool(int maxPoolSize, int queueSize) {
executor = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),
maxPoolSize,120L, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(queueSize));
}
public void execute(Runnable task){
executor.execute(task);
}
}
public class MultiplexerTimeServer implements Runnable {
private Selector selector;
private ServerSocketChannel acceptorSvr;
private volatile boolean stop;
public MultiplexerTimeServer (int port){
try {
acceptorSvr = ServerSocketChannel.open();
//绑定端口
acceptorSvr.socket().bind(new InetSocketAddress(port));
//设置非阻塞
acceptorSvr.configureBlocking(false);
selector=Selector.open();
acceptorSvr.register(selector,SelectionKey.OP_ACCEPT);
System.out.println("time server 在端口:"+port+" 上启动");
} catch (IOException e) {
System.exit(1);
}
}
@Override
public void run() {
while (!stop){
try {
selector.select(1000);
Set<SelectionKey> selectionKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator=selectionKeys.iterator();
SelectionKey selectionKey;
while (iterator.hasNext()){
selectionKey =iterator.next();
iterator.remove();
try {
handleInput(selectionKey);
}catch (Exception e){
if (selectionKey!=null){
selectionKey.cancel();
if (selectionKey.channel()!=null){
selectionKey.channel().close();
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
if (selector!=null){//关闭多路复用器,channel会自动被关闭
try {
selector.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void handleInput(SelectionKey selectionKey) throws IOException {
if (selectionKey.isValid()){
if (selectionKey.isAcceptable()){
ServerSocketChannel ssc= (ServerSocketChannel) selectionKey.channel();
SocketChannel sc=ssc.accept();
sc.configureBlocking(false);
sc.register(selector,SelectionKey.OP_READ);
}
if (selectionKey.isReadable()){
SocketChannel sc= (SocketChannel) selectionKey.channel();
ByteBuffer readBuffer = ByteBuffer.allocate(1024);
int readBytes=sc.read(readBuffer);
if (readBytes>0){
readBuffer.flip();
byte[] bytes = new byte[readBuffer.remaining()];
readBuffer.get(bytes);
String body=new String(bytes,"utf-8");
String currentTime =new Date(System.currentTimeMillis()).toString();
doWrite(sc,currentTime+"\r\n");
} else if (readBytes < 0){
//对端链路关闭
selectionKey.cancel();
sc.close();
}else {
//读到0字节,忽略
}
}
}
}
private void doWrite(SocketChannel sc, String currentTime) throws IOException {
if (currentTime!=null && currentTime.trim().length()>0){
byte[] bs = currentTime.getBytes();
ByteBuffer wb=ByteBuffer.allocate(bs.length);
wb.put(bs);
wb.flip();
sc.write(wb);
}
}
}
客户端:
public class TimeClientHandler implements Runnable {
private String host;
private int port;
private Selector selector;
private SocketChannel socketChannel;
private volatile boolean stop;
public static void main(String[] args) {
Thread t= new Thread(new TimeClientHandler(null,8000));
t.setDaemon(false);
t.start();
}
public TimeClientHandler(String host,int port){
this.host=host==null?"127.0.0.1":host;
this.port=port;
try {
selector =Selector.open();
socketChannel =SocketChannel.open();
socketChannel.configureBlocking(false);
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
}
@Override
public void run() {
try {
doConnect();
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
while (!stop){
try {
selector.select(1000);
Set<SelectionKey> selectionKeys=selector.selectedKeys();
Iterator<SelectionKey> iterator=selectionKeys.iterator();
while (iterator.hasNext()){
SelectionKey selectionKey=iterator.next();
iterator.remove();
try {
handleInput(selectionKey);
}catch (Exception e){
selectionKey.cancel();
if (selectionKey.channel()!=null)
selectionKey.channel().close();
}
}
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
}
if (selector!=null){
try {
selector.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void handleInput(SelectionKey selectionKey) throws IOException {
if (selectionKey.isValid()){
SocketChannel sc= (SocketChannel) selectionKey.channel();
if (selectionKey.isConnectable()){
if(sc.finishConnect()) {
sc.register(selector, SelectionKey.OP_READ);
doWrite(sc);
}else {
System.exit(1);
}
}
if (selectionKey.isReadable()){
ByteBuffer readBuf=ByteBuffer.allocate(1024);
int readBytes = sc.read(readBuf);
if (readBytes>0){
readBuf.flip();
byte[] bytes=new byte[readBuf.remaining()];
readBuf.get(bytes);
String body=new String(bytes,"utf-8");
System.out.println("now is:"+body);
this.stop=true;
}else if (readBytes<0){
selectionKey.cancel();
sc.close();
}else {
}
}
}
}
private void doConnect() throws IOException{
//如果直接连接成功,则注册到多路复用器上,发送请求消息,读应答
if (socketChannel.connect(new InetSocketAddress(host,port))){
socketChannel.register(selector, SelectionKey.OP_READ);
doWrite(socketChannel);
}else {
socketChannel.register(selector,SelectionKey.OP_CONNECT);
}
}
private void doWrite(SocketChannel socketChannel) throws IOException {
byte[] req="Query time order".getBytes();
ByteBuffer byteBuffer=ByteBuffer.allocate(req.length);
byteBuffer.put(req);
byteBuffer.flip();
socketChannel.write(byteBuffer);
if (!byteBuffer.hasRemaining()){
System.out.println("发送成功");
}
}
}
AIO编程
服务端:
public class TimeServer {
public static void main(String[] args) {
int port=8000;
if (args!=null && args.length>0){
try {
port=Integer.parseInt(args[0]);
}catch (NumberFormatException e){
}
}
AsyncServer timeServer=new AsyncServer(port);
new Thread(timeServer,"aio-async").start();
}
}
public class AsyncServer implements Runnable{
private int port;
CountDownLatch latch;
AsynchronousServerSocketChannel asynchronousServerSocketChannel;
public AsyncServer(int port) {
this.port=port;
try {
asynchronousServerSocketChannel=AsynchronousServerSocketChannel.open();
asynchronousServerSocketChannel.bind(new InetSocketAddress(port));
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
System.out.println("服务启动");
latch=new CountDownLatch(1);
doAccept();
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void doAccept() {
asynchronousServerSocketChannel.accept(this,
new AcceptCompletionHandler());
}
}
public class AcceptCompletionHandler implements CompletionHandler<AsynchronousSocketChannel, AsyncServer> {
@Override
public void completed(AsynchronousSocketChannel result, AsyncServer attachment) {
attachment.asynchronousServerSocketChannel.accept(attachment,this);
java.nio.ByteBuffer buffer= java.nio.ByteBuffer.allocate(1024);
result.read(buffer,buffer,new ReadCompletionHandler(result));
}
@Override
public void failed(Throwable exc, AsyncServer attachment) {
exc.printStackTrace();
attachment.latch.countDown();
}
}
public class ReadCompletionHandler implements CompletionHandler<Integer, ByteBuffer> {
private AsynchronousSocketChannel channel;
public ReadCompletionHandler(AsynchronousSocketChannel result) {
if (this.channel==null){
this.channel=result;
}
}
@Override
public void completed(Integer result, ByteBuffer attachment) {
attachment.flip();
byte[] body = new byte[attachment.remaining()];
attachment.get(body);
try {
String req =new String(body,"UTF-8");
String currentTime=new Date().toString();
doWrite(currentTime);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
private void doWrite(String currentTime) {
if (currentTime!=null && currentTime.trim().length()>0){
byte[] bytes=currentTime.getBytes();
ByteBuffer wbuffer=ByteBuffer.allocate(bytes.length);
wbuffer.put(bytes);
wbuffer.flip();
channel.write(wbuffer, wbuffer, new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer result, ByteBuffer attachment) {
if (attachment.hasRemaining()){
channel.write(attachment,attachment,this);
}
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
try {
channel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
try {
this.channel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端:
public class AsyncClient {
public static void main(String[] args) {
int port=8000;
if (args!=null && args.length>0){
try {
port=Integer.parseInt(args[0]);
}catch (NumberFormatException e){
}
}
AsyTimeClientHandler clientHandler= new AsyTimeClientHandler("127.0.0.1",port);
new Thread( clientHandler,"aio-async").start();
}
}
public class AsyTimeClientHandler implements Runnable, CompletionHandler<Void,AsyTimeClientHandler > {
private AsynchronousSocketChannel client;
private String host;
private int port;
private CountDownLatch latch;
public AsyTimeClientHandler(String host, int port) {
this.host=host;
this.port=port;
try {
client=AsynchronousSocketChannel.open();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
latch= new CountDownLatch(1);
client.connect(new InetSocketAddress(host,port),this,this);
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void completed(Void result, AsyTimeClientHandler attachment) {
byte[] req="hello .".getBytes();
ByteBuffer wbuf=ByteBuffer.allocate(req.length);
wbuf.put(req);
wbuf.flip();
client.write(wbuf, wbuf, new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer result, ByteBuffer attachment) {
if (attachment.hasRemaining()){
client.write(attachment,attachment,this);
} else {
ByteBuffer readBuffer=ByteBuffer.allocate(1024);
client.read(
readBuffer,
readBuffer,
new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer result, ByteBuffer attachment) {
attachment.flip();
byte[] bytes=new byte[attachment.remaining()];
attachment.get(bytes);
String body;
try {
body=new String(bytes,"utf-8");
System.out.println("时间是:"+body);
latch.countDown();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
latch.countDown();
}
}
);
}
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
try {
client.close();
latch.countDown();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
@Override
public void failed(Throwable exc, AsyTimeClientHandler attachment) {
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
latch.countDown();
}
}