【问题标题】:I can't catch SocketTimeoutException()我无法捕捉到 SocketTimeoutException()
【发布时间】:2015-01-06 11:14:41
【问题描述】:

解决方案:在下面查看我的答案

我有一个服务器/客户端聊天应用程序,其中客户端使用 P2P 进行通信(每个内部都有一个小服务器)。所以每个客户端都有一个线程,它应该不断地监控是否有消息进入任何连接的套接字(=其他客户端)。但是因为 BufferedReader 中的 readLine() 方法阻塞了,我想使用 SocketTimeoutException 来中断它,这样每个 Socket 都会被监控一小会儿,然后切换到下一个。

Socket tmp = add.getSocket();
try{
  tmp.setSoTimeout(2000);
  Communication com = new Communication(tmp);
  System.out.println(com.get());
} catch(SocketTimeoutException e){
  if(!running)return;
} catch(SocketException e){
    e.printStackTrace();
}

( -- 通信获取一个 Socket 并管理该 Socket 的 InputStreams。com.get() 是 只是一个调用 in.readLine() 的方法,其中 in 是 InputStream 的 BufferedReader --)

但是编译器说 try 块中从来没有抛出 SocketTimeoutException。 但是,如果我没有捕捉到异常,那么在超时之后我会得到 SocketTimeoutException。 我不知道如何解决这个问题

编辑:

get() 方法

 public String get() throws SocketTimeoutException {
                String str = null;
                try{
                        if(s.isClosed()==false) str =  in.readLine();
                } catch (IOException e){
                         if(e.getCause() instanceof SocketTimeoutException) {
                                 throw new SocketTimeoutException();
                        }
                         e.printStackTrace();
                }
                        return str;
        }


java.net.SocketTimeoutException: Read timed out
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.read(SocketInputStream.java:152)
    at java.net.SocketInputStream.read(SocketInputStream.java:122)
    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:283)
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:325)
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:177)
    at java.io.InputStreamReader.read(InputStreamReader.java:184)
    at java.io.BufferedReader.fill(BufferedReader.java:154)
    at java.io.BufferedReader.readLine(BufferedReader.java:317)
    at java.io.BufferedReader.readLine(BufferedReader.java:382)
    at Communication.get(Communication.java:46)
    at ListeningThread.run(ListeningThread.java:26)

ListeningThread.run() 是嵌入第一个代码 sn-p 的函数。 第26行是行

System.out.println(com.get());

【问题讨论】:

  • 请显示抛出SocketTimeoutException的代码
  • 您刚刚删除的评论中的代码永远不会真正抛出SocketTimeoutException,即使它已声明这样做。通过捕获IOException,它也正在捕获SocketTimeoutException
  • ConnectException extends SocketTimeOutException 这个问题在同一问题上有一个雄辩的答案goo.gl/OYfFJW
  • 我在原帖中编辑了方法。 @EJP 除了抛出 SocketTimeoutException 之外,还有什么方法可以打破 readLine() 锁?除了我尝试的方式之外,我如何捕获由 read() 引起的 SocketTimeoutException?

标签: java sockets exception client server


【解决方案1】:

好的,异常现在消失了! 这是更新后的 get() 函数:

    public String get() throws SocketTimeoutException {
            String str = null;
            try{
                    if(s.isClosed()==false) str =  in.readLine();
            } catch (IOException e){
                    try{
                            if(e instanceof SocketTimeoutException) {
                                    throw new SocketTimeoutException();
                            }
                    } catch (SocketTimeoutException f){
                    }
            }
                    return str;
    }

请注意在第二个 try{} 块之前缺少 e.printStackTrace()。感谢所有帮助过我的人!

【讨论】:

    【解决方案2】:

    SocketTimeoutException 扩展了 InterruptedIOException,后者扩展了 IOException。 所以,正如 EJP 所说,如果抛出这个异常,get 方法的 catch 块会捕获它。

    【讨论】:

    • 所以我检查了 IOException 是否为 instanceof SocketTimeoutException,如果是则抛出一个新的 SocketTimeoutException。但是,catch 块仍然没有捕获它
    • 你能把你用于这个修改的代码sn-p吗?
    • 能否也附上异常日志?
    • 只是为了确保这个堆栈跟踪来自 IOException 捕获块,只需在 sysout 中打印一些消息而不是堆栈跟踪并共享结果。例如:catch(IOException ex){System.out.println( "In IOExcpetion block");} 对其他 catch 块也做同样的事情。
    • 没有输入“instanceof” if-block
    【解决方案3】:

    可能是完全不同的问题,但以下代码的一个常见/次要问题

    catch(SocketTimeoutException e){
      if(!running)return;
    } 
    

    使用这段代码,即使发生异常,您也不会看到异常。这称为异常吞咽。显示e.printStackTrace 以获取输出中的异常。

    【讨论】:

    • 我想要的是“打破” readLine() 块,也许使用 return 结束程序
    猜你喜欢
    • 2015-07-21
    • 2015-01-24
    • 1970-01-01
    • 2021-07-10
    • 1970-01-01
    • 2017-04-22
    • 1970-01-01
    • 1970-01-01
    • 2018-06-08
    相关资源
    最近更新 更多