gpt4 book ai didi

java - 在 Java 中,为什么 readLine() 会阻塞已关闭的套接字连接?

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:29:44 24 4
gpt4 key购买 nike

我有一个简单的客户端/服务器应用程序。服务器设置为如果在 N 秒内没有数据进入,则会发生超时并关闭套接字连接。我通过 Socket.setSoTimeout() 执行此操作。如果客户端挂起,一切正常。但是,如果客户端死了(例如,我用 Ctrl-C 杀死它),那么 readLine() 永远不会超时。

这是服务器代码,如果有区别的话:

public void run()
{
PrintWriter out = null;
BufferedReader in = null;

try {
sock.setSoTimeout(10000);

out = new PrintWriter(sock.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(sock.getInputStream()));

String input;
while ((input = in.readLine()) != null) {

我已经尝试将信号处理程序放入客户端以向服务器发送 ABEND 消息,但这不起作用(我怀疑在发送 ABEND 之前套接字已关闭,但我并没有真正花费任何时间试图弄清楚)。

有没有办法定期唤醒并检查套接字状态以查看它是否已关闭?或者(更好的是)如果套接字关闭则没有 readLine() 挂起?我应该使用某种无缓冲的阅读器吗?是否存在支持类似 readLine 机制的无缓冲读取器?

我在 Linux 上使用 Java 6。

编辑:我在闲置期间自己杀死了客户;此时已发送和接收所有数据。我已经(通过 ps)验证客户端程序不再运行; Java进程确实被杀死了。使用 netstat 我可以看到套接字在两端都已关闭,但 readLine() 仍然挂起。

最佳答案

我认为您误诊了问题。

如果套接字的输入端已关闭,则 readLine() 调用应该看到该关闭。在消耗完所有缓冲数据后,调用应返回一个 null。 (如果套接字正常关闭,您不会得到 IOException,但如果连接超时,您可能会得到一个……例如。)

最明显的解释是套接字还没有关闭。查看另一端将关闭套接字的情况,并弄清楚为什么还没有发生这种情况。


这些都不是解决方案,但我会回答完整性问题。

Is there a way to wake up periodically and check the socket state to see if it's closed?

另一个线程可以做到这一点,但这个不行。

Or (better yet) not have readLine() hang if the socket closes?

这就是应该发生的事情。

Should I be using an unbuffered reader of some sort?

没用。您最终不得不自己实现 readLine(),并且您的代码会在同一点阻塞。阻塞行为发生在阅读器链的缓冲层和字符解码层下方

Does an unbuffered reader supporting a readLine-like mechanism exist?

不,它没有。见上文。

关于java - 在 Java 中,为什么 readLine() 会阻塞已关闭的套接字连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14752760/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com