开发者

Java NIO: connection forcibly closed

开发者 https://www.devze.com 2023-03-18 18:18 出处:网络
I was trying to implement a simple HTTP client using java NIO. But I get an error that the connection was forcibly closed by the remote host before the all data was read.

I was trying to implement a simple HTTP client using java NIO. But I get an error that the connection was forcibly closed by the remote host before the all data was read. Using ordinary sockets, everything works fine.

Here's an example:

private static final String REQUEST = "GET / HTTP/1.1\r\nHost: stackoverflow.com\r\n\r\n";

void channel() {
    try {
        SocketChannel sc = SocketChannel.open(new InetSocketAddress("stackoverflow.com", 80));
        while (!sc.isConnected()) {
        }

        ByteBuffer buf = ByteBuffer.allocate(16*1024);
        buf.put(REQUEST.getBytes());
        buf.rewind();
        sc.write(buf);

        buf.rewind();
        while (sc.read(buf) > 0) {
            buf.rewind();
            System.out.println(new String(buf.array()));
            buf.clear();
        }

    } catch (IOException e) {
        e.printStackTrace();
    }
}

void socket() {
    try {
        Socket s = new Socket("stackoverflow.com", 80);
        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
        BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));

        out.write(REQUEST);
        out.flush();

        String l;
        while ((l = in.readLine()) != null) {
            System.out.println(l);
        }
 开发者_运维技巧   } catch (IOException e) {
        e.printStackTrace();
    }
}

public static void main(String[] args) {
    // Works:
    new Test().socket();
    // Exception:
    new Test().channel();
}

This is the exception I get:

java.io.IOException: An existing connection was forcibly closed by the remote host
at sun.nio.ch.SocketDispatcher.read0(Native Method)
at sun.nio.ch.SocketDispatcher.read(Unknown Source)
at sun.nio.ch.IOUtil.readIntoNativeBuffer(Unknown Source)
at sun.nio.ch.IOUtil.read(Unknown Source)
at sun.nio.ch.SocketChannelImpl.read(Unknown Source)
at at.maph.tlsproxy.client.Test.channel(Test.java:39)
at at.maph.tlsproxy.client.Test.main(Test.java:70)

Has it something to do that I'm using a buffered reader with the socket, but not with the channel? If so, how can I make a channel buffer the read data?


Ok, I figured it out now after checking write()'s return value, which was 16.384, so random data was sent to the server. The problem was with calling rewind on the buffer, instead, flip has to be used:

void channel() {
    try {
        SocketChannel sc = SocketChannel.open(new InetSocketAddress("stackoverflow.com", 80));

        ByteBuffer buf = ByteBuffer.allocate(16*1024);
        buf.put(REQUEST.getBytes());
        buf.flip();     // <--------- Here
        sc.write(buf);

        buf.rewind();
        while (sc.read(buf) > 0) {
            buf.flip();   // <------- And here
            System.out.println(new String(buf.array()));
            buf.clear();
        }

    } catch (IOException e) {
        e.printStackTrace();
    }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号