为什么NIO选择器总是侦听端口列表中的最后一个端口?

用户名

以下是我的代码供您查看。1.我正在使用在3个端口上发送数据的仿真器。但是我的代码从端口列表的最后一个端口写入数据。例如,端口2002,3002,4002和代码仅侦听4002。NIO选择器必须转向所有端口。

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
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;
import java.nio.charset.CharsetDecoder;
import java.util.Iterator;
import java.util.Set;
public class ServerSockets {

     public static void main(String[] args) throws IOException 
     {
         int ports[] = new int[] {2002,3002,4002};
         Selector selector =null;

        // loop through each port in our list and bind it to a ServerSocketChannel
        for (int port : ports) {
            ServerSocketChannel serverChannel = ServerSocketChannel.open();
            serverChannel.configureBlocking(false);
            serverChannel.socket().bind(new InetSocketAddress(port));
            selector = Selector.open();
            serverChannel.register(selector, SelectionKey.OP_ACCEPT);
        }


 //check for all port whom ready to send data
 while (true) {

     // our canned response for now
     ByteBuffer resp = ByteBuffer.wrap(new String("got it\n").getBytes());
     try {
         // loop over all the sockets that are ready for some activity
         while (selector.select() > 0) {
             Set keys = selector.selectedKeys();
             Iterator i = keys.iterator();
             while (i.hasNext()) {
                 SelectionKey key = (SelectionKey)i.next();
                 if (key.isAcceptable()) {
                     // this means that a new client has hit the port our main
                     // socket is listening on, so we need to accept the  connection
                     // and add the new client socket to our select pool for reading
                     // a command later
                     System.out.println("Accepting connection!");
                     // this will be the ServerSocketChannel we initially registered
                     // with the selector in main()
                     ServerSocketChannel sch = (ServerSocketChannel)key.channel();
                     SocketChannel ch = sch.accept();
                     ch.configureBlocking(false);
                     ch.register(selector, SelectionKey.OP_READ);
                 } else if (key.isReadable()) {
                     // one of our client sockets has received a command and
                     // we're now ready to read it in
                     System.out.println("Accepting command!");                            
                     SocketChannel ch = (SocketChannel)key.channel();
                     ByteBuffer buf = ByteBuffer.allocate(200);
                     ch.read(buf);
                     buf.flip();
                     Charset charset = Charset.forName("UTF-8");
                     CharsetDecoder decoder = charset.newDecoder();
                     CharBuffer cbuf = decoder.decode(buf);
                     System.out.print(cbuf.toString());
                     // re-register this socket with the selector, this time
                     // for writing since we'll want to write something to it
                     // on the next go-around
                   // ch.register(selector, SelectionKey.OP_READ);
                 } else if (key.isWritable()) {
                     // we are ready to send a response to one of the client sockets
                     // we had read a command from previously
                     System.out.println("Sending response!");
                     SocketChannel ch = (SocketChannel)key.channel();
                     ch.write(resp);
                     resp.rewind();
                     // we may get another command from this guy, so prepare
                     // to read again. We could also close the channel, but
                     // that sort of defeats the whole purpose of doing async
                     ch.register(selector, SelectionKey.OP_READ);
                 }
                 i.remove();
             }
         }
     } catch (IOException e) {
         System.out.println("Error in poll loop");
         System.out.println(e.getMessage());
         System.exit(1);
     }
 }

}}

用户名

您要创建Selector多次,因此最终只能使用创建的最后一个,而创建的最后一个仅在其中ServerSocketChannel注册。将其从循环中移到开始之前。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

一个HashMap中,增加了一个新的元素到桶的内部链接列表的总是在最后。为什么?

创建一个侦听端口的简单Rust守护程序

新行中第一个和最后一个内联块元素的选择器

为什么事件侦听器仅在for循环中创建的最后一个元素上注册?

Elastic Load Balancer侦听器不适用于一个端口

为什么日期选择器中的日期显示最后一天?

为什么我的列表视图总是删除列表中的最后一个视图

为什么不能选择数组的最后一个索引?

为什么我无法在选择器视图列表中选择我的第一个数据?

单击多个选择器的最后一个元素

为什么浏览器会忽略我CSS文件中的第一个选择器?

为什么侦听器数组的长度是3,而不是最后一个console.log中的2?

在选择器中链接.attr()时,为什么jQuery只选择一个元素?

为什么CSS选择器返回一个元素数组?

为什么此Python代码仅在一个端口上侦听?

为什么前面URL中的另一个端口获得HTTP流量?

最后一个选择器

jQuery选择器查找最后一个元素

:last选择器在jQuery中找不到最后一个元素

为什么jQuery选择器只返回页面中包含的框架中的一个元素?

为什么只有第一个CSS选择器起作用?

Laravel 5中有2个日期选择器,但仅保存了最后一个值

为什么要桥接一个端口?

为什么 jQuery 类选择器只返回一个元素?

javascript中是否有任何内置函数可以使用类选择器或元素选择器来选择最后一个元素?

如何在一个元素中添加多个带有选择器的事件侦听器?

如何在 React Native 中做最后一个子选择器?

Vue.js 使用伪选择器选择 div 中的最后一个元素

将变量分配给一个选择器并使最后一个子项在 javascript 中工作