Java / Groovy Socket - 检测以非阻塞方式关闭的套接字
我正在尝试创建一个小型 HTTP 代理,它可以根据需要重写请求/标头以满足我的要求。如果已经存在,请指出它。否则......
我已经写了一些几乎有效的东西。它可以执行代理功能,但还不能执行重写。问题是,如果不进行阻塞读取,我无法检测远程套接字何时关闭。对于这个东西的功能来说至关重要的是它能够检测到套接字正在关闭而不会阻塞。我已经浏览了 Java API 文档,但我找不到任何迹象表明这是可能的。这就是我所拥有的:
while ( this.inbound.isConnected() && this.outbound.isConnected() ) {
try {
while ( ( available = readFromClient.available() ) != 0 ) {
if ( available > 1024 ) available = 1024
bytesRead = readFromClient.read( buffer, 0, available )
writeToServer.write( buffer, 0, bytesRead )
}
while ( ( available = readFromServer.available() ) != 0 ) {
if ( available > 1024 ) available = 1024
bytesRead = readFromServer.read( buffer, 0, available )
writeToClient.write( buffer, 0, bytesRead )
}
} catch (e) {
print e
}
println "Connected: " + this.inbound.isConnected()
println "Bound: " + this.inbound.isBound()
println "InputShutdown: " + this.inbound.isInputShutdown()
println "OutputShutdown: " + this.inbound.isOutputShutdown()
print "\n";
Thread.sleep( 10 )
}
对正在关闭的套接字的测试从未表明套接字已关闭。而且,正如我所提到的,我找不到任何有关如何在不进行阻塞读取的情况下检测流上的“文件结束”条件的示例。
一定有办法。这里有人知道它是什么吗?
I'm trying to create a small HTTP proxy that can re-write the request/headers as needed to suit my requirements. If one already exists, please, point me to it. Otherwise...
I've written something that ALMOST works. It can do the proxy function, but not the re-write (yet). Problem is, I can't detect when the remote socket has been closed down without doing a blocking read. It is CRITICAL for the functionality of this thing that it be able to detect the socket being closed without blocking. I have SCOURED the Java API documentation, and I can't find ANY indication that it is even possible. Here's what I have:
while ( this.inbound.isConnected() && this.outbound.isConnected() ) {
try {
while ( ( available = readFromClient.available() ) != 0 ) {
if ( available > 1024 ) available = 1024
bytesRead = readFromClient.read( buffer, 0, available )
writeToServer.write( buffer, 0, bytesRead )
}
while ( ( available = readFromServer.available() ) != 0 ) {
if ( available > 1024 ) available = 1024
bytesRead = readFromServer.read( buffer, 0, available )
writeToClient.write( buffer, 0, bytesRead )
}
} catch (e) {
print e
}
println "Connected: " + this.inbound.isConnected()
println "Bound: " + this.inbound.isBound()
println "InputShutdown: " + this.inbound.isInputShutdown()
println "OutputShutdown: " + this.inbound.isOutputShutdown()
print "\n";
Thread.sleep( 10 )
}
The tests for the socket being closed never indicate that the socket was closed. And, as I mentioned, I can't find ANY examples of how to detect the 'END OF FILE' condition on the stream without doing a blocking read.
There HAS to be a way. Does anyone here know what it is?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我假设您正在使用
java.net.Socket
进行 I/O。为了在 Java 中进行非阻塞 I/O,您必须使用 NIO 包。特别是,您需要使用 java.nio.channels.SocketChannel 进行通信。在通道上调用
configureBlocking(false)
,然后 read() 将返回读取的数据量,-1 表示关闭,如果没有可用数据则返回 0。在某些错误情况下也可能引发异常。这是一个 示例,显示非 -使用 SocketChannel 阻塞 I/O。
I'm assuming you're using
java.net.Socket
for your I/O. In order to do non-blocking I/O in Java, you have to use the NIO package.In particular, you'll want to use a
java.nio.channels.SocketChannel
for communication. CallconfigureBlocking(false)
on the channel, then read() will either return the amount of data read, -1 for closed, or zero if no data is available. An exception could be thrown on some error conditions as well.Here's an example showing non-blocking I/O using a SocketChannel.
不,这没有帮助。如果连接在另一端关闭,并且 java nio 选择器在发生这种情况时没有将通道放入就绪集中,您怎么知道您应该读取呢?
据我所知,它只是被设计破坏了,而且没有办法做到这一点。如果我错了,请有人纠正我...
No, this doesn't help. How can you even know that you're supposed to read if the connection is shut-down on the other side, and the java nio selector doesn't put the channel in the ready set when this happens?
It's just broken by design so far as I can tell, and there's no way to do this. Please someone correct me if I'm mistaken...