2015-09-29 57 views
3

我想重现“java.net.SocketException.Connection重置”异常。如何重现“java.net.SocketException.Connection重置”?

想知道是否有任何程序可以帮助我模拟它。我尝试了以下服务器和客户端程序,看看我是否可以模拟,但我无法得到任何异常。我正在使用java8。

服务器代码 -

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.net.ServerSocket; 
import java.net.Socket; 
import java.net.SocketException; 
import java.net.SocketTimeoutException; 


public class SimpleServerApp { 

    public static void main(String[] args) throws InterruptedException { 

     new Thread(new SimpleServer()).start(); 

    } 

    static class SimpleServer implements Runnable { 

     @Override 
     public void run() { 

      ServerSocket serverSocket = null; 

      try { 
       serverSocket = new ServerSocket(3333); 
       serverSocket.setSoTimeout(0); 

       //serverSocket. 
       while (true) { 
        try { 
         Socket clientSocket = serverSocket.accept(); 

         BufferedReader inputReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); 

         System.out.println("Client said :"+ inputReader.readLine()); 

        } catch (SocketTimeoutException e) { 
         e.printStackTrace(); 
        } 
       } 

      }catch (Exception e) { 
       e.printStackTrace(); 
       System.out.println(" EXCEPTION " + e.getStackTrace()); 
      }/*catch (IOException e1) { 
       e1.printStackTrace(); 
      }*/ /*finally { 
       try { 
        if (serverSocket != null) { 
         serverSocket.close(); 
        } 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      }*/ 

     } 

    } 
} 

客户端代码 -

import java.io.IOException; 
import java.io.PrintWriter; 
import java.net.Socket; 
import java.net.SocketException; 
import java.net.UnknownHostException; 


public class SimpleClientApp { 

    public static void main(String[] args) { 

     new Thread(new SimpleClient()).start(); 

    } 

    static class SimpleClient implements Runnable { 

     @Override 
     public void run() { 

      Socket socket = null; 
      try { 

       socket = new Socket("localhost", 3333); 


       PrintWriter outWriter = new PrintWriter(socket.getOutputStream(), true); 

       System.out.println("Wait"); 

       Thread.sleep(20000); 
       //System.exit(0); 
       //throw new Exception("Random exception"); 
       //socket.close(); 

       outWriter.println("Hello Mr. Server!"); 

      }catch (SocketException e) { 
       e.printStackTrace(); 
      }catch (InterruptedException e) { 
       e.printStackTrace(); 
      } catch (UnknownHostException e) { 
       e.printStackTrace(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } catch (Exception e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } /*finally { 

       try { 
        if (socket != null) 
         socket.close(); 
       } catch (IOException e) { 

        e.printStackTrace(); 
       } 


      } 
*/  } 

    } 

} 

方案1.

  • 本地启动服务器程序。
  • 本地启动客户端程序。
  • 关闭客户端程序突然(按Ctrl C) - 我刚上 服务器程序输出 “客户说:空”

场景2.

  • 启动本地服务器程序。
  • 本地启动客户端程序。
  • 客户端连接到服务器,然后在客户端程序正在等待关闭服务器程序时突然。仍然不例外。

有些人可以告诉我一些方法我可以产生连接重置异常,工作示例代码。

回答

1

这个工作对我来说:

class Server { 

    public static void main(String[] args) throws Exception { 
     ServerSocket ss = new ServerSocket(9999); 
     Socket s = ss.accept(); 
     InputStream i = s.getInputStream(); 
     i.read(); 
    } 
} 

客户端连接和断开连接不上服务器关闭套接字

class Client { 

    public static void main(String[] args) throws Exception { 
     Socket s = new Socket("localhost", 9999); 
    } 
} 

这导致例外

Exception in thread "main" java.net.SocketException: Connection reset 
    at java.net.SocketInputStream.read(Unknown Source) 
    at java.net.SocketInputStream.read(Unknown Source) 
    at java.net.SocketInputStream.read(Unknown Source) 
    at net.Server.main(Server.java:13) 
+0

我累了你的服务器程序,但我没有得到任何异常。我甚至尝试修改它这样 '公共类AnotherServer { \t公共静态无效的主要(字串[] args)抛出异常{ \t \t尝试{ \t \t \t ServerSocket的SS =新ServerSocket的(9999) ; \t \t \t Socket s = ss.accept(); \t \t \t InputStream i = s.getInputStream(); \t \t \t i.read(); (例外e){ \t \t} catch(Exception e){ \t \t \t e.printStackTrace(); (“THE EXCEPTION”+ e.getStackTrace()); \t \t} \t} }' 但我仍是无法得到异常。我使用mac和java8 incase如果有帮助 – kalpesh

+3

这是平台相关的。 Windows的行为就像这样。我认为Unix不会。 – EJP

+0

这是我试过的 1.在Mac上运行的服务器程序,在Windows上运行的客户端程序,然后运行@Evgeniy Dorofeev的程序我可以在Mac上看到连接重置异常。 2.我在Windows上运行Server程序,在Mac上运行客户端程序,但没有看到连接重置异常。 我想我只是想尝试在Linux上的另一种情况来仔细检查是否有任何连接重置异常来。但我认为异常将会依赖于平台。 – kalpesh

1

有几种方法。我不会发布其中的一个,因为它实在是太多了虐待,但简单的方法来生产它是:

  1. 关闭套接字马上你获得它,不读任何东西。如果发件人正在发送给您而不是从您那里阅读,则此功能起作用。
  2. 如果您知道发件人已发送内容,请关闭套接字但不以任何方式读取它。
3

上面的这些答案在Mac和Linux上都可靠地工作。 经过大量的谷歌搜索,我结束了这个article解释如何做到这一点。只是要清楚:我试图从客户端复制连接重置,即“通过对等方重置连接”。

我试着调出一个运行netcat的进程,并突然终止进程 - 这只能在Mac上运行。

我尝试了socket.close从另一个线程,同一个线程 - 没有任何工作。

简而言之,所有这些方法都不会导致客户端向服务器发送RST,从而导致异常(由对等方重置)。

以下工作:

  • 安装任何服务器 - 在我的情况Netty中(其入门放弃服务器都行)。
  • 使用下面的客户端代码: final Socket socket = new Socket("localhost", port);; socket.setSoLinger(true, 0); final OutputStream outputStream = socket.getOutputStream(); for (int i=0;i <= 500;i++) { outputStream.write('a'); } outputStream.write('\n'); outputStream.flush(); socket.close();

    Thread.sleep(2000); 
    

的soLinger()是魔术。根据上面引用的Oracle文章,当你调用socket.close()时,它将RST发送到另一端,而不是发送FIN,然后等待另一端完成读取发送到FIN的所有内容 - 即强制关闭。

我花了1天的时间才发现这一点,所以我希望它能为您节省工作时间。