2016-12-27 51 views
0

我在缓冲读卡器连接TCP套接字,并在自己的线程的套接字上打开一个缓冲阅读器的I/O,然后读取使用的readLine数据时触发异常:BufferedReader中在Java中失败尝试从封闭套接字读取

try { 
    socket = new Socket(targetHost, targetPort); 
    ou = new PrintWriter(socket.getOutputStream(), true); 
    in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 

    while (true) { 
    message = in.readLine(); 
    ... 
    process the data 
    ... 
    } 
} catch (Exception e) { 
    e.printStackTrace(); 
    return; 
} 

只要连接存在,就可以正常工作。但是,当TCP连接的另一端意外消失时,在大约75%的情况下,该线程从未意识到对方已经消失,并且任何尝试从缓冲读取器读取的操作都会产生一个“空”字符串,但没有例外,我也无法关闭线程,因为它不知道对方已经离开了。在大约25%的情况下,线程被终止(也没有产生异常),但是产生期望的结果,我只需要线程在TCP连接断开时消失。

我试图用这个弄清楚,如果连接还活着:

boolean connected = socket.isConnected() && !socket.isClosed(); 

但是,这并不工作,当对方已经走了,线程不断啮咬总是返回true。

任何想法的人?

+0

定义“消失”。 TCP连接的工作方式,如果另一端关闭连接,则应该看到异常。但是,如果另一端变得无法访问(例如,拔下了电缆或关闭了服务器,则在TCP计算出错误之前会有很长的超时时间。 –

+0

离开意味着另一端的程序决定退出。不会崩溃,但退出。这意味着它关闭TCP连接。当连接被删除,不应该有在客户端检测到的事件? – Balthasar

+1

它在哪里说这应该抛出一个异常?为什么不您停止阅读时'的readLine()'返回null,这意味着“流的末尾”,按的Javadoc?这就是“事件”你正在寻找。 – EJP

回答

2

的问题基本上是:“可以作为设计的”。

读者返回null,实际上是指:“没有更多的数据,我在这里做了。”

javadoc

返回:包含该行的内容,不包括任何行终止符或字符串空如果该流的末尾已到达

在其它单词:关闭的套接字在此处被视为“正常”操作;因此没有例外。换句话说:您必须更改您的代码以检查readLine()的结果是否返回null;如果是这样,你知道套接字已经消失了。

+0

但是,如上所述,TCP连接的另一端不仅仅是拔下,它关闭,即套接字关闭,应该有一个可检测到的事件 – Balthasar

+2

@Bthathas有。 'readLine()'返回null。 – EJP

+1

@EJP谢谢。我正在寻找一个现有的问题,以dup结束,但没有找到这个问题。另一方面,这两个upvotes提升我超过25K。自由一台!所以,我不介意。 – GhostCat

相关问题