SocketChannel 死循环在读消息
/* * 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); } }}
os.write(mes.getBytes());
os.flush();
os.close();
s.close();
只发送给服务端一次消息 为什么客户端 死循环在 读消息呢?
这个是为什么,我没有一直在连接服务端阿!谁能解决下阿 谢谢拉
控制台信息invoke startServer---------------------nKeys=1测试此键的通道是否已准备好接受新的套接字连接nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!nKeys=1read a message from client!。。。。。。死循环下去了
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!"); } } } } }