如何重现“ java.net.SocketException.Connection重置”?

kal*_*esh 3 java socketexception java-8

我正在尝试重现“ 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();
                }
            }*/

        }

    }
}
Run Code Online (Sandbox Code Playgroud)

客户代码-

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();
                }


            }
*/      }

    }

}
Run Code Online (Sandbox Code Playgroud)

场景1。

  • 在本地启动服务器程序。
  • 在本地启动客户端程序。
  • 突然关闭客户端程序(Ctrl C)-我只是在服务器程序“ Client said:null”上得到输出

场景2。

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

有人可以告诉我用工作示例代码生成连接重置异常的方法。

Asa*_*ika 5

在Mac和Linux上,以上答案均无法可靠地为我工作。经过大量的Google搜索,我在本文结尾处解释了如何执行此操作。只是要清楚一点:我试图从客户端重现连接重置,即“按对等方重置连接”。

我试图提出一个运行netcat的进程,并突然终止该进程-仅在Mac上有效。

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

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

以下工作:

  • 设置任何服务器-在我的例子中是Netty(他们的入门Discard服务器会做)。
  • 使用以下客户端代码:
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);
Run Code Online (Sandbox Code Playgroud)

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

我花了1天的时间才能找到答案,所以我希望它可以节省您的工作时间。