Simulating “Connection reset by peer” exception in Unit Testing using Java

Asaf Mesika
2 min readDec 5, 2015

--

If you have TCP server which has certain logic operating only when you get “Connection reset by peer” IOException, you’d want to test that in Unit testing, right? It should work reliably both on Mac and Linux at the very least.

It took me half a day to track the solution on doing it. Before I start, let’s mention what doesn’t work:

  1. Creating a process running netcat, and then killing it works only on Mac and not on Linux.
  2. Creating a Socket, writing to it and just closing it
  3. Creating a socket, setting soTimeout to 1ms — won’t work, since it’s the timeout for socket accept() and read(). Since we’re simulating the client, we’re not really reading here, but writing (I assume the server just receives traffic and doesn’t respond back). Apparently Java doesn’t support write timeout.
  4. Calling socket.close from another thread doesn’t work

The solution lies within this article. Apparently, to get this exception you must have the client send a RST command on the TCP protocol. This can happen programmatically in Java if you do this:

socket.setSoLinger(true, 0)
socket.close()

Upon closing the socket, Java sends a RST instead of FIN and it works!

Here’s a small code that shows it

package com.mesika.server.tcp.test;

import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.test.AvailablePortFinder;
import org.apache.camel.test.junit4.CamelTestSupport;
import org.junit.Test;

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;

/**
* @author amesika
*
*/
public class ResetByPeerTest extends CamelTestSupport {

private int port;

@Override
protected RouteBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
@Override
public void configure() throws Exception {
port = AvailablePortFinder.getNextAvailable();
from(String.format("netty4:tcp://localhost:%d?textline=true&sync=false", port))
.filter(e -> {return false;})
.to("log:OFF");
}
};
}

@Test
public void sanity() throws IOException, InterruptedException {
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);
}


}

This test uses Apache Camel, which is the easiest way I found to have a mock TCP server up and running in 1 min.

I hope I saved you couple of frustrating hours of work!

--

--

Asaf Mesika

A 20 years experienced software engineer specializing in building application infrastructure based on Java and its open source eco-system. Java.IL co-founder.