0

我正在尝试使用 NIO 实现一个简单的客户端-服务器应用程序。

作为一个练习,交流应该是基于文本和面向行的。但是当服务器读取客户端发送的字节时,它什么也得不到,或者更确切地说,缓冲区充满了一堆零。

我正在使用选择器,这是在通道可读时触发的代码。

private void handleRead() throws IOException {
    System.out.println("Handler Read");
    while (lineIndex < 0) {
        buffer.clear();
        switch (channel.read(buffer)) {
            case -1:
            // Close the connection.
            return;

            case 0:
            System.out.println("Nothing to read.");
            return;

            default:
            System.out.println("Converting to String...");
            buffer.flip();
            bufferToString();
            break;
        }
    }
    // Do something with the line read.
}

在这个片段中,lineIndex是一个int持有第一次\n发生的索引,当阅读时。它用 初始化-1,表示不\n存在。

变量buffer引用 a ByteBuffer,并channel表示 a SocketChannel

为了简单起见,没有Charsets 和诸如此类的东西,这bufferToString是编码方式:

private void bufferToString() {
    char c;
    System.out.println("-- Buffer to String --");
    for (int i = builder.length(); buffer.remaining() > 1; ++i) {
        c = buffer.getChar();
        builder.append(c);
        System.out.println("Appending: " + c + "(" + (int) c + ")");
        if (c == '\n' && lineIndex < 0) {
            System.out.println("Found a new-line character!");
            lineIndex = i;
        }
    }
}

该变量builder包含对 a 的引用StringBuilder

我希望getChar进行合理的转换,但我在输出中得到的只是一堆(对应于缓冲区容量的一半)

附加:(0)

终止于

没什么可读的。

任何可能是什么原因的线索?我在客户端有类似的代码,也无法从服务器正确读取任何内容。


如果有任何帮助,以下是编写代码的示例:

private void handleWrite() throws IOException {
    buffer.clear();
    String msg = "Some message\n";
    for (int i = 0; i < msg.length(); ++i) {
        buffer.putChar(msg.charAt(i));
    }
    channel.write(buffer);
}

我还确认结果channel.write大于零,确保字节确实被写入和发送。

4

1 回答 1

3

原来,这是一个缓冲区索引问题。在服务器中,flip()在写入套接字之前缺少 a。在客户端代码中,也有一些flip()在阅读之后和写作之前丢失了。现在一切都按预期工作。

当前编写代码(服务器端):

private void handleWrite() throws IOException {
    String s = extractLine();
    for (int i = 0, len = s.length(); i < len;) {
        buffer.clear();
        while (buffer.remaining() > 1 && i < len) {
            buffer.putChar(s.charAt(i));
            ++i;
        }
        buffer.flip();
        channel.write(buffer);
    }
    // some other operations...
}
于 2013-10-13T14:23:49.040 回答