Java网络编程-Nio 实例代码

来源:互联网 发布:孙禄堂 知乎 编辑:程序博客网 时间:2024/06/10 04:35


  IO NIO 区别请看 : http://blog.csdn.net/jiangtao_st/article/details/38041479


一、基于Nio的 Server ,过程略复杂,但是无疑这样的效率高;代码中得注释比较详细,请看注释说明

package com.zhuoxuan.net.nio;import java.io.IOException;import java.net.InetSocketAddress;import java.net.ServerSocket;import java.nio.ByteBuffer;import java.nio.channels.SelectionKey;import java.nio.channels.Selector;import java.nio.channels.ServerSocketChannel;import java.nio.channels.SocketChannel;import java.util.Iterator;import java.util.Random;import java.util.Set;/** *  * <p> * 基于nio的Server * </p> *  * @author 卓轩 * @创建时间:2014年7月7日 * @version: V1.0 */public class NioServer {private final int port = 8787;private final int BLOCK_SIZE = 4096;private Selector selector;private ByteBuffer receiveBuffer = ByteBuffer.allocate(BLOCK_SIZE);private ByteBuffer sendBuffer = ByteBuffer.allocate(BLOCK_SIZE);//构造函数public NioServer() throws IOException {//打开服务器套接字通道 ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();//服务器配置为非阻塞模式serverSocketChannel.configureBlocking(false);//获取与通道关联的 ServerSocket对象ServerSocket serverSocket = serverSocketChannel.socket();//绑定端口serverSocket.bind(new InetSocketAddress(port));//打开一个选择器selector = Selector.open();//注册到selector上,等待连接serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);System.out.println("Server:init successfuly.");}/** * 监听端口 */private void linstenr() throws Exception{while (true) {//选择一组键selector.select();//返回获取选择的键集Set<SelectionKey> selectionKeys = selector.selectedKeys();if(selectionKeys.isEmpty()){continue;}//遍历,循环处理请求的键集Iterator<SelectionKey> iterator =  selectionKeys.iterator();while (iterator.hasNext()) {SelectionKey selectionKey = (SelectionKey) iterator.next();iterator.remove();handlerKey(selectionKey);}Thread.sleep(4000);}}/** * 处理对应的  SelectionKey * @param selectionKey */private void handlerKey(SelectionKey selectionKey) throws IOException{ServerSocketChannel server;SocketChannel client;// 测试此键的通道是否已准备好接受新的套接字连接if(selectionKey.isAcceptable()){//此键对应的关联通道server = (ServerSocketChannel)selectionKey.channel();//接受到此通道套接字的连接client = server.accept();//配置为非阻塞client.configureBlocking(false);//注册到selector 等待连接client.register(selector, SelectionKey.OP_READ);}else if (selectionKey.isReadable()) {client = (SocketChannel)selectionKey.channel();//将缓冲区清空,下面读取receiveBuffer.clear();//将客户端发送来的数据读取到 buffer中int count = client.read(receiveBuffer);if(count >0){String receiveMessage = new String(receiveBuffer.array(),0,count);System.out.println("Server:接受客户端的数据:" + receiveMessage);client.register(selector, SelectionKey.OP_WRITE);}}else if (selectionKey.isWritable()) {//发送消息buffer 清空sendBuffer.clear();//返回该键对应的通道client = (SocketChannel)selectionKey.channel();String sendMessage = "Send form Server...Hello... "+new Random().nextInt(100)+" .";//向缓冲区中写入数据sendBuffer.put(sendMessage.getBytes());//put了数据,标志位被改变sendBuffer.flip();//数据输出到通道client.write(sendBuffer);System.out.println("Server:服务器向客户端发送数据:" + sendMessage);client.register(selector, SelectionKey.OP_READ);}}public static void main(String[] args) {try {NioServer nioServer = new NioServer();nioServer.linstenr();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}}


二、Nio Client 实例

package com.zhuoxuan.net.nio;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.SelectionKey;import java.nio.channels.Selector;import java.nio.channels.SocketChannel;import java.util.Iterator;import java.util.Set;/** *  * <p> *   nio client * </p> *  * @author 卓轩 * @创建时间:2014年7月7日 * @version: V1.0 */public class NioClient {private static final int BLOCK_SIZE = 4096;private static ByteBuffer sendBuffer = ByteBuffer.allocate(BLOCK_SIZE);private static ByteBuffer receiveBuffer = ByteBuffer.allocate(BLOCK_SIZE);private static final  InetSocketAddress SERVER_ADDRESS = new InetSocketAddress("127.0.0.1",8787);public static void main(String[] args) {try {//打开socket通道SocketChannel socketChannel = SocketChannel.open();//设置为非阻塞模式socketChannel.configureBlocking(false);//打开选择器Selector selector = Selector.open();//向selector 选择器注册此通道socketChannel.register(selector, SelectionKey.OP_CONNECT);//链接socketChannel.connect(SERVER_ADDRESS);SocketChannel client;while (true) {//选择一组键selector.select();//返回此选择器的已选择键集Set<SelectionKey> selectionKeys = selector.selectedKeys();Iterator<SelectionKey> iterator = selectionKeys.iterator();//遍历对应的 SelectionKey 处理while (iterator.hasNext()) {SelectionKey selectionKey = (SelectionKey) iterator.next();//判断此键的通道是否已完成其套接字连接操作if (selectionKey.isConnectable()) {System.out.println("Client:  already connected.");client = (SocketChannel)selectionKey.channel();//判断该通道是否进行连接过程、完成连接过程if(client.isConnectionPending()){client.finishConnect();sendBuffer.clear();sendBuffer.put("hello nio server".getBytes());sendBuffer.flip();client.write(sendBuffer); //将数据写入该通道client.register(selector, SelectionKey.OP_READ);}}else if(selectionKey.isReadable()){//获取该键中对应的通道client = (SocketChannel)selectionKey.channel();receiveBuffer.clear();int count = client.read(receiveBuffer);if(count > 0){String receiveMessage = new String(receiveBuffer.array(),0,count);System.out.println("Client:接收到来自Server的消息," + receiveMessage);client.register(selector, SelectionKey.OP_WRITE);}}else if(selectionKey.isWritable()){sendBuffer.clear();                      client = (SocketChannel) selectionKey.channel();                      String sendText = "hello server,key..";                    sendBuffer.put(sendText.getBytes());                       //将缓冲区各标志复位,因为向里面put了数据标志被改变要想从中读取数据发向服务器,就要复位                      sendBuffer.flip();                      client.write(sendBuffer);                      System.out.println("Client:客户端向服务器端发送数据--:"+sendText);                      client.register(selector, SelectionKey.OP_READ);}}selectionKeys.clear();Thread.sleep(3000);}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}}



0 0
原创粉丝点击