Java NIO:连接强行关闭
我试图使用 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)
我在套接字上使用缓冲读取器而不是在通道上有什么关系吗?如果是这样,我怎样才能让通道缓冲读取的数据?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
好吧,在检查了 write() 的返回值后我现在明白了,它是 16.384,所以随机数据被发送到服务器。问题在于调用
在缓冲区上倒带
,而不是翻转
必须使用: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 callingrewind
on the buffer, instead,flip
has to be used: