日期:2014-05-20 浏览次数:20836 次
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package testsocketchannel; import java.io.IOException; import java.io.OutputStream; import java.net.InetSocketAddress; import java.net.Socket; 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.Set; import java.util.logging.Level; import java.util.logging.Logger; /** * * @author root */ public class Main implements Runnable { /** * @param args the command line arguments */ public static void main(String[] args) throws IOException, InterruptedException { // TODO code application logic here //启动 serversockechannel Main main=new Main(); Thread t=new Thread(main); t.start(); //休眠,防止server没有及时启动 Thread.sleep(1000); //连接server 发送消息 String mes="send a message"; Socket s=new Socket("127.0.0.1", 9000); OutputStream os=s.getOutputStream(); os.write(mes.getBytes()); os.flush(); os.close(); s.close(); } //start server public void run(){ try { Selector selector; ServerSocketChannel ssc; SocketChannel sc; boolean stop = true; System.out.println("invoke startServer---------------------"); int nKeys = 0; selector = Selector.open(); // 打开一个选择器 ssc = ServerSocketChannel.open(); //打开服务器套接字通道。 InetSocketAddress add = new InetSocketAddress(9000); ssc.socket().bind(add); ssc.configureBlocking(false); //调整此通道的阻塞模式 true为阻塞 false为非阻塞 SelectionKey seletK = ssc.register(selector, SelectionKey.OP_ACCEPT); //向给定的选择器注册此通道,返回一个选择键。 while (stop) { synchronized (this) { nKeys = selector.select(); //选择一组键,其相应的通道已为 I/O 操作准备就绪。返回已更新其准备就绪操作集的键的数目、 System.out.println("nKeys=" + nKeys); if (nKeys > 0) { Set<SelectionKey> selectedKeys = selector.selectedKeys(); //返回此选择器的已选择键集。 Iterator i = selectedKeys.iterator(); //返回在此 set 中的元素上进行迭代的迭代器 while (i.hasNext()) { //如果仍有元素可以迭代,则返回 true seletK = (SelectionKey) i.next(); //返回迭代的下一个元素。 i.remove(); if (seletK.isAcceptable()) { //测试此键的通道是否已准备好接受新的套接字连接 System.out.println("测试此键的通道是否已准备好接受新的套接字连接"); Socket socket = ((ServerSocketChannel) seletK.channel()).accept().socket(); // 获取与此通道关联的套接字。 sc = socket.getChannel(); //返回与此数据报套接字关联的唯一 SocketChannel 对象 sc.configureBlocking(false); sc.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE); } if (seletK.isReadable()) { //测试此键的通道是否已准备好进行读取。 System.out.println("read a message from client!"); } } } } } } catch (IOException ex) { Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); } } }