孩子不是海子 2017-06-02 01:16 采纳率: 9.1%
浏览 1020

java nio通信问题如何解决

        大佬们帮我看看这句代码,我有点理解不了:![图片说明](https://img-ask.csdn.net/upload/201706/02/1496365514_646261.png)

这句代码的前面是获取欲与服务器端建立联系的selectionkey的作用,但是server.accept()这句代码并没有和相应的selectionkey对应,jdk只是说这句代码的作用只是获取此刻与服务器channel建立连接的socketchannel而不是此刻正在被检查的selectionkey的对应的socketchannel,那前面的那句sk.isAccpetable()不就起不到作用了吗?请知道的大侠告诉下。代码如下:
public class NServer
{
//用于检测所有Channel状态的Selector
private Selector selector=null;
static final int PORT=3334;
//定义实现编码、解码的字符集对象
private Charset charset=Charset.forName("UTF-8");
public void init()
{
try {
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(true) //说明有需要处理的IO对象
{
if(selector.select()==0)continue;
//依次处理selector上的每个选择的SelectionKey
for(SelectionKey sk :selector.selectedKeys())
{
//从selector上的已选择Key集中删除正在处理的SelectionKey
selector.selectedKeys().remove(sk);
//如果sk对应的Channel包含客户端的连接请求
if(sk.isAcceptable())
{
//调用accept方法接受连接,产生服务端的SocketChannel
SocketChannel sc=server.accept();
//设置采用非阻塞模式
if (sc == null) {

continue;

}

sc.configureBlocking(false);
//将该SocketChannel也注册到selector
//后面的read表示我们可以向通道那里读入数据了
// System.out.println("@@@@@@@@@@@@");
sc.register(selector, SelectionKey.OP_READ);
//将sk对应的Channel设置成准备接收其他请求
//sk.interestOps(SelectionKey.OP_ACCEPT);

           }
         //如果sk对应的Channel有数据需要读取
              if(sk.isReadable())
               {
                  //System.out.println("@@@@@@@@@@@@");
        //获取该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+=charset.decode(buff);
                       }
          //打印从该sk对应的Channel里读取到的数据
                    while(sc.write(buff)>0)
                      {
                          buff.clear();
                          content+=charset.decode(buff);
                      }
         //将sk对应的Channel设置成准备下一次读取
                   sk.interestOps(SelectionKey.OP_READ);
                   System.out.println("Server收到信息了: "+content);
                       if(content.length()<5)
                          {
                            sc.write(charset.encode("你发过来的长度小于5"));
                          }
                       else if(content.length()<9)
                          {
                             sc.write(charset.encode("你发过来的长度小于9"));
                          }
                     }catch(IOException ex)
                        {
           //从Selector中删除指定的SelectionKey
                            sk.cancel();
                              if(sk.channel()!=null)
                                    {
                                         sk.channel().close();
                                   }
                        }

        //sc.write(charset.encode(line));

 }

}
}
} catch (IOException e) {
// TODO 自动生成的 catch 块
//System.out.println("出错了");
e.printStackTrace();
}

}
class Thread3 extends Thread
{
public void run()
{
init();
System.out.println("结束了");
}
}

                  public static void main(String[]args)
                    {
                       new NServer().new Thread3().start();
                    }
            }
  • 写回答

1条回答 默认 最新

  • 关注

    isAcceptable() 这个方法是 测试此键的通道是否已准备好接受新的套接字连接。
    accept() 方法是 接受到此通道套接字的连接。

    评论

报告相同问题?

悬赏问题

  • ¥50 永磁型步进电机PID算法
  • ¥15 sqlite 附加(attach database)加密数据库时,返回26是什么原因呢?
  • ¥88 找成都本地经验丰富懂小程序开发的技术大咖
  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥200 uniapp长期运行卡死问题解决
  • ¥15 latex怎么处理论文引理引用参考文献
  • ¥15 请教:如何用postman调用本地虚拟机区块链接上的合约?
  • ¥15 为什么使用javacv转封装rtsp为rtmp时出现如下问题:[h264 @ 000000004faf7500]no frame?