有没有办法在特定的时间内读取输入流?
我遇到一种情况,线程打开到目标 m/c 的 telnet 连接,并从程序中读取数据,该程序吐出其缓冲区中的所有数据。当所有数据被刷新后,目标程序打印一个标记。我的线程不断寻找这个标记来关闭连接(成功读取)。
有时,目标程序不打印任何标记,它继续转储数据,而我的线程继续读取它(目标程序不打印任何标记)。
所以我只想读取特定时间段的数据(比如 15 分钟/可配置)。有没有办法在java API级别做到这一点?
I've a situation where a thread opens a telnet connection to a target m/c and reads the data from a program which spits out the all the data in its buffer. After all the data is flushed out, the target program prints a marker. My thread keeps looking for this marker to close the connection (successful read).
Some times, the target program does not print any marker, it keeps on dumping the data and my thread keeps on reading it (no marker is printed by the target program).
So i want to read the data only for a specific period of time (say 15 mins/configurable). Is there any way to do this at the java API level?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
15 分钟后使用另一个线程关闭连接。或者,您可以在每次读取后检查是否已经过去了 15 分钟,然后简单地停止读取并清理连接,但这只有在您确定远程服务器将继续发送数据时才有效(如果没有,读取将被阻止)无限期)。
Use another thread to close the connection after 15 mins. Alternatively, you could check after each read if 15mins have passed and then simply stop reading and cleanup the connection, but this would only work if you're sure the remote server will continue to send data (if it doesn't the read will block indefinitely).
一般来说,不会。输入流不提供超时功能。
但是,在您的具体情况下,即从套接字读取数据,是的。您需要做的是 设置将套接字上的 SO_TIMEOUT 设置为非零值(您需要的超时时间,以毫秒为单位)。任何阻塞指定时间的读取操作都会抛出
SocketTimeoutException
。
但请注意,即使您的套接字连接在此之后仍然有效,继续从中读取可能会带来意外的结果,因为您已经消耗了一半的数据。处理此问题的最简单方法是关闭连接,但如果您跟踪已阅读的内容,则可以选择恢复并继续阅读。
Generally, no. Input streams don't provide timeout functinality.
However, in your specific case, that is, reading data from a socket, yes. What you need to do is set the SO_TIMEOUT on your socket to a non-zero value (the timeout you need in millisecs). Any read operations that block for the amount of time specified will throw a
SocketTimeoutException
.Watch out though, as even though your socket connection is still valid after this, continuing to read from it may bring unexpected result, as you've already half consumed your data. The easiest way to handle this is to close the connection but if you keep track of how much you've read already, you can choose to recover and continue reading.
如果您使用 Java Socket 进行通信,则应该查看 setSoTimeout(int) 方法。
套接字上的 read() 操作将仅阻塞指定的时间。之后,如果没有收到任何信息,则会引发
java.net.SocketTimeoutException
,如果处理正确,则会继续执行。If you're using a Java Socket for your communication, you should have a look at the setSoTimeout(int) method.
The read() operation on the socket will block only for the specified time. After that, if no information is received, a
java.net.SocketTimeoutException
will be raised and if treated correctly, the execution will continue.如果服务器真的永久转储数据,则客户端将永远不会被阻塞在读取操作中。因此,您可以定期检查(在读取之间)当前时间减去开始时间是否超过了可配置的延迟,如果超过则停止读取。
如果客户端可以在同步读取中被阻止,等待服务器输出某些内容,那么您可以使用 SocketChannel,并启动一个计时器线程,该线程会中断主读取线程,或关闭其输入,或关闭通道。
If the server really dumps data forever, the client will never be blocked in a read operation. You might thus regularly check (between reads) if the current time minus the start time has exceeded your configurable delay, and stop reading if it has.
If the client can be blocked in a synchronous read, waiting for the server to output something, then you might use a SocketChannel, and start a timer thread that interrupts the main reading thread, or shuts down its input, or closes the channel.