0

我正在使用 Java NIO 编写一个简单的 HTTP 服务器,但很早就陷入了沉默。我有以下代码:

Selector accept = Selector.open();
            ServerSocketChannel ssc = ServerSocketChannel.open();
            ssc.configureBlocking(false);

            InetAddress lh = InetAddress.getByName("127.0.0.1");
            InetSocketAddress isa = new InetSocketAddress(lh, port);
            ssc.socket().bind(isa);
            SelectionKey acceptKey = ssc.register(accept,
                    SelectionKey.OP_ACCEPT);

            while (accept.select() > 0) {
                Set<SelectionKey> readyKeys = accept.selectedKeys();
                Iterator<SelectionKey> i = readyKeys.iterator();

                while (i.hasNext()) {
                    SelectionKey sk = i.next();
                    if (sk.isAcceptable()) {
                        System.out.println("Is acceptable");
                        ssc = (ServerSocketChannel) sk.channel();
                        SocketChannel sc = ssc.accept();
                        sc.configureBlocking(false);
                        sc.register(accept, SelectionKey.OP_READ);
                        System.out.println("Registered new SocketChannel");
                    }
                    if (sk.isReadable()) {
                        SocketChannel sc = (SocketChannel) sk.channel();
                        ByteBuffer buffer = ByteBuffer.allocate(20000);
                        buffer.clear();
                        int bytesRead = sc.read(buffer);
                        buffer.flip();

                        while (buffer.hasRemaining()) {
                            System.out.print((char) buffer.get());
                        }

                        buffer.clear();
                    }
                    i.remove();
                }
            }

现在,如果我在浏览器中打开两个选项卡并导航到 localhost:8080,这将是应用程序的输出:

Is acceptable
Registered new SocketChannel
Is acceptable
Registered new SocketChannel
GET / HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8

Is acceptable
Registered new SocketChannel

现在我有两个问题:1)为什么我一开始会得到一个额外的接受事件?2)为什么没有收到第二个http请求?连接被接受,它的 SocketChannel 正在选择器中注册。但是没有收到请求正文。我知道生成了许多“空”读取事件,但它们都没有带来请求正文。

4

2 回答 2

1
  1. 为什么我在开始时会收到一个额外的接受事件?

    • 仅当您从浏览器发起请求时才会发生这种情况。
    • 如果您使用简单的套接字/http 客户端创建连接,您将只收到一个接受请求。(虽然您需要修改您的读取代码以在读取返回-1时关闭套接字)。
  2. 为什么没有收到第二个http请求?

  3. 在 IE 中检查此行为

    • 修改代码以在连接关闭时执行读取时处理异常(在 catch 块 sc.close() 和 sk.cancel() 中)
    • 从 IE 发起请求
    • 2 接受 + 1 读已收到
    • 在 IE 中取消请求
    • 等待一段时间并在同一选项卡中再次发起请求
    • 只收到一个读取,没有接受请求
    • 现在再次转到同一选项卡并取消请求
    • 现在再次从同一选项卡发起请求
    • 同样的两个接受+一个阅读
    • 以上使我相信#2点可能会创建第二个连接以用于备份目的
于 2013-06-10T08:29:53.540 回答
1
  1. 您有三个接受事件。
  2. 可能是因为你没有回复第一个。
  3. “空”读取事件可能已关闭,您忽略了它。

尝试修复所有这些并重新测试。当你不这样做时,你不能指望对等方表现自己。

于 2013-06-10T01:44:26.167 回答