java nio实现非阻塞Socket通信实例
2013-11-04 13:48
183 查看
服务器
package com.java.xiong.Net17; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.Channel; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.nio.charset.Charset; public class NServer { // 用于检测所有的Channel状态的selector private Selector selector = null; static final int PORT = 30000; // 定义实现编码、解码的字符串集对象 private Charset charse = Charset.forName("GBK"); public void init() throws IOException { selector = Selector.open(); // 通过open方法来打开一个未绑定的ServerSocketChannel是咧 ServerSocketChannel server = ServerSocketChannel.open(); InetSocketAddress isa = new InetSocketAddress("127.0.0.1", PORT); // 将该ServerSocketChannel绑定到指定的IP地址 server.bind(isa); // 设置serverSocket已非阻塞方式工作 server.configureBlocking(false); // 将server注册到指定的selector对象 server.register(selector, SelectionKey.OP_ACCEPT); while (selector.select() > 0) { // 一次处理selector上的每个选择的SelectionKey for (SelectionKey sk : selector.selectedKeys()) { // 从selector上已选择的Kye集中删除正在处理的SelectionKey selector.selectedKeys().remove(sk); // 如果sk对应的Channel包含客户端的连接请求 if (sk.isAcceptable()) { // 调用accept方法接收连接,产生服务器段的SocketChennal SocketChannel sc = server.accept(); // 设置采用非阻塞模式 sc.configureBlocking(false); // 将该SocketChannel注册到selector sc.register(selector, SelectionKey.OP_READ); } // 如果sk对应的Channel有数据需要读取 if (sk.isReadable()) { // 获取该SelectionKey对银行的Channel,该Channel中有刻度的数据 SocketChannel sc = (SocketChannel) sk.channel(); // 定义备注执行读取数据源的ByteBuffer ByteBuffer buff = ByteBuffer.allocate(1024); String content = ""; // 开始读取数据 try { while (sc.read(buff) > 0) { buff.flip(); content += charse.decode(buff); } System.out.println("读取的数据:" + content); // 将sk对应的Channel设置成准备下一次读取 sk.interestOps(SelectionKey.OP_READ); } // 如果捕获到该sk对银行的Channel出现了异常,表明 // Channel对应的Client出现了问题,所以从Selector中取消 catch (IOException io) { // 从Selector中删除指定的SelectionKey sk.cancel(); if (sk.channel() != null) { sk.channel().close(); } } // 如果content的长度大于0,则连天信息不为空 if (content.length() > 0) { // 遍历selector里注册的所有SelectionKey for (SelectionKey key : selector.keys()) { // 获取该key对应的Channel Channel targerChannel = key.channel(); // 如果该Channel是SocketChannel对象 if (targerChannel instanceof SocketChannel) { // 将读取到的内容写入该Channel中 SocketChannel dest = (SocketChannel) targerChannel; dest.write(charse.encode(content)); } } } } } } } public static void main(String [] args) throws IOException{ new NServer().init(); } }
客户端
package com.java.xiong.Net17; import java.io.IOException; 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.nio.charset.Charset; import java.util.Scanner; public class NClient { //定义检测Sockethannel的Selector对象 private Selector selector=null; static final int PORT=30000; //定义处理编码的字符集 private Charset charset=Charset.forName("GBK"); //客户端SocketChannel private SocketChannel sc=null; public void init() throws IOException{ selector=Selector.open(); InetSocketAddress isa=new InetSocketAddress("127.0.0.1", PORT); //调用open的静态方法创建连接指定的主机的SocketChannel sc=SocketChannel.open(isa); //设置该sc已非阻塞的方式工作 sc.configureBlocking(false); //将SocketChannel对象注册到指定的Selector sc.register(selector, SelectionKey.OP_READ); //启动读取服务器数据端的线程 new ClientThread().start(); //创建键盘输入流 Scanner scan=new Scanner(System.in); while(scan.hasNextLine()){ //读取键盘的输入 String line=scan.nextLine(); //将键盘的内容输出到SocketChanenel中 sc.write(charset.encode(line)); } } //定义读取服务器端的数据的线程 private class ClientThread extends Thread{ @Override public void run() { try{ while(selector.select()>0){ //遍历每个有可能的IO操作的Channel对银行的SelectionKey for(SelectionKey sk:selector.selectedKeys()){ //删除正在处理的SelectionKey selector.selectedKeys().remove(sk); //如果该SelectionKey对应的Channel中有可读的数据 if(sk.isReadable()){ //使用NIO读取Channel中的数据 SocketChannel sc=(SocketChannel)sk.channel(); String content=""; ByteBuffer bff=ByteBuffer.allocate(1024); while(sc.read(bff)>0){ sc.read(bff); bff.flip(); content+=charset.decode(bff); } //打印读取的内容 System.out.println("聊天信息:"+content); sk.interestOps(SelectionKey.OP_READ); } } } }catch(IOException io){ io.printStackTrace(); } } } public static void main(String [] args) throws IOException{ new NClient().init(); } }
相关文章推荐
- java nio实现非阻塞Socket通信实例
- C语言实现socket简单通信实例
- 【Socket编程二】利用Socket实现聊天通信的编程实例
- Flex通信-与Java实现Socket通信实例
- Java网络编程——使用NIO实现非阻塞Socket通信
- Lock和Condition实现线程通信(附阻塞队列的实例)
- Java网络编程——使用NIO实现非阻塞Socket通信
- Java NIO 非阻塞socket通信案例
- 手写JAVA NIO实现Socket通信及其过程中注意的问题
- java分布式开发TCP/IP NIO无阻塞 Socket((基于消息方式实现系统间的通信) )(转)
- java 网络通信socket实现简单实例
- 用PHP的socket实现客户端到服务端的通信实例详解
- Java NIO实例-ServerSocketChannel实现Socket传输
- Kqueue 实现非阻塞 Socket 通信
- 基于Java NIO 的socket通信实例
- 使用NIO实现非阻塞Socket通信原理
- Flex通信-与Java实现Socket通信实例
- Java实现的基于socket通信的实例代码
- socket 实例实现简单通信
- java nio 操作(2)异步阻塞 socket实现