Skip to content
Advertisement

Java Socket how to simulate disconection from server

I have a Java program with a client and server sockets, there I want to test that an exception is raised after the server is down.

This is the server:

public class SocketServer implements Runnable {
  private bool serverRuns = false;
  private int timeout = 10000;
  private DataInputStream in;
  private DataOutputStream out;
  private Socket client;
  private ServerSocket server;
  private String message = "Ok";
  private waitForInstruction = true;


  public SocketServer() throws IOException {
    ServerSocket server = new ServerSocket(tcpPort,0,ipAdress);
    serverRuns = true;
    server.setSoTimeout(timeout)
  }

  private void waitForClient() {
    try {
      client = server.accept();
      client.setSoTimeout(timeout);
      in = new DataInputStream(client.getInputStream());
      out = new DataOutputStream(client.getOutputStream());
    } catch (IOException e) {
      fail("I/O Error " + e.getMessage());
    }
   }

  public void run() {
    waitForClient();

    while (serverRuns) {
      if (clientSocket.isClosed()) {
         waitForClient();
      }

      try {
        while (waitForInstruction == false) {
          // Read input message
          String inputStreamString = "";
          while (in.available() > 0) {
            int c = in.read();
            inputStreamString += (char) c;
          } 
          out.write(message.getBytes());
          System.out.println("Sent bytes: " + out.size());
          setWaitForInstruction(true);
        }
      } catch (IOException E) {
        fail("I/O Error " + E.getMessage());
      }
    }
  }


public void closeServerSocket() {
    try {
      serverRuns = false;
      serverSocket.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

void setWaitForInstruction(boolean waitForInstruction) {
    this.waitForInstruction = waitForInstruction;
  }
    
  public void startServerSocket() {
    serverRuns = true;
  }
}

This is the client:

public class SocketClient extends Socket {
  private InetAddress address;
  private short tcpPort;
  private DataInputStream in;
  private DataOutputStream out;
  private static final int timeOut = 10000;

  public SocketClient(InetAddress address, short tcpPort) {
    this.tcpPort = tcpPort;
    this.address = address;
  }
  public void connect() throws IOException, SocketTimeoutException {
    super.connect(new InetSocketAddress(address, tcpPort), timeOut);
  }

  public void doStuff() throws IOException {
    String request = "Ok?";
    String InputStreamString = "";

    super.setSoTimeout(timeOut);
    this.setSoTimeout(timeOut);
    out = new DataOutputStream(super.getOutputStream());
    in = new DataInputStream(super.getInputStream());

    out.writeBytes(requestString);

    int c;
    do {
      if (in.available() > 0) {
        c = in.read();
        InputStreamString += (char) c;
      }
    } while (!InputStreamString.equals("Ok"));
    System.out.println(InputStreamString);

  }
}

I start the server socket thread with:

 @BeforeClass
 public static void startSocket() throws IOException {
      testServer = new SocketServer();
      monitor = new Thread(testServer);
      monitor.setName("Test Server Thread");
      monitor.setDaemon(true);
      monitor.start();
  }

And the JUnit test is this:

@Before
public void createSocket() throws Exception {
  ipAdress = InetAddress.getLocalHost();
  SystemConfig.setLoggerConfigFilePath("LoggerConfig.xml");

  socketClient = new SocketClient(ipAdress, 5000);
}


@Test
  public void checkServerisDown() {
    try {
      socketClient.connect();
    } catch (IOException e) {
       fail("IO Error");
    }

    testServer.closeServerSocket();
    monitor.interrupt();

   try {
     testServer = new SocketServer();

     monitor = new Thread(testServer);
     monitor.setName(" Test Server Thread");
     monitor.setDaemon(true);
    // monitor.start();

    testServer.startServerSocket();
    testServer.setWaitForInstruction(false);

    System.out.print("Test (1/1) CHECK SERVER IS DOWN.....n");
    socketClient.doStuff();
    System.out.println("NOT OK!");

  } catch (IOException e) {   
    fail("IO Error " + e.getMessage() + " OK"); 
  }

  try {
    drEstimControlInterface.close();
    testServer.getSocket().close();
  } catch (IOException e) {
    fail("IO Error");
  }
}

  @AfterClass
  public static void closeSocket() throws IOException {
    testServer.closeSocket();
  }

However the test is not performing as I intended, I thought that this should return an IOException since the server socket has been closed and the thread has been interrupted, but the client socket still gets the answer from the server socket and prints the “NOT OK!”. Could anybody tell me why?

Advertisement

Answer

You have to close not only ServerSocket but client socket with streams too.

public void closeServerSocket() {
    try {
      serverRuns = false;
      serverSocket.close();
      in.close();
      out.close();
      client.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement