我试图使用java NIO实现一个简单的HTTP客户端。但是我得到一个错误,即在读取所有数据之前,远程主机强行关闭了连接。 使用普通的插座,一切正常。
以下是一个例子:
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();
}
这是我得到的例外:
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)
有没有什么可以做的,我正在使用带套接字的缓冲读卡器,但没有使用频道?如果是这样,我如何使通道缓冲读取数据?
答案 0 :(得分:0)
好的,我在检查write()
的返回值(16.384)之后现在想出来了,所以随机数据被发送到服务器。问题是在缓冲区上调用rewind
,而是必须使用flip
:
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();
}
}