2

I want to see how a HTTP client reacts to connection timeouts, i.e. where there's a server listening on a port, but the process of setting up the connection is so slow that the client gives up and returns a connection timeout. The connection shouldn't be refused, and it shouldn't be accepted and then followed by a socket timeout.

So far, I've attempted to introduce network delay by overriding ServerSocket, imagining that I would be able to write something like this...

public SlowServerSocket extends ServerSocket {
    // (This method doesn't actually exist).
    @Override
    public void processBytesPassedOnByOperatingSystem(byte[] bytes) {
        Thread.sleep(delay);
        // Client has already returned a connection timeout.
        super.processBytesPassedOnByOperatingSystem(bytes);
    }
}

...but I run into a dead end when I get to that level of abstraction (it seems to be hidden in a native method). My fake server accepts connections and then does nothing, causing a socket timeout.

I've also looked for solutions online, and I came across SlowSocket from the JMeter library, but it seems to be used on the client-side (and I don't think I'll be able to override the client so that it uses SlowSocket).

Any suggestions?

Pig
  • 485
  • 4
  • 14
  • 1
    Note: I found this answer, https://stackoverflow.com/questions/100841/artificially-create-a-connection-timeout-error, which suggests connecting to a non-routable address, such as "10.255.255.1". However, I'm not sure that it's the most reliable / portable solution. – Pig Jul 05 '17 at 15:48
  • It might also be worth subclassing `SecurityManager` and overriding the `checkAccept()` method so that it sleeps, then calling System.setSecurityManager(overridenSecurityManager). Idea comes from here: https://stackoverflow.com/questions/7800960/java-socket-listen-before-accept?rq=1 – Pig Jul 05 '17 at 16:16

2 Answers2

0

I want to see how a HTTP client reacts to connection timeouts, i.e. where there's a server listening on a port, but the process of setting up the connection is so slow that the client gives up and returns a connection timeout.

Your requirement embodies a contradiction in terms. A connect timeout occurs when the peer host doesn't respond at all, usually because of a firewall. It has nothing to do with the server application being slow. The server doesn't 'set up the connection': the TCP stack does.

The connection shouldn't be refused

It won't be if there is a listening process, except as below.

and it shouldn't be accepted and then followed by a socket timeout.

This is exactly what the code you have written will produce.

However, and if and only if the server platform isn't Windows, there is another way to produce a connect timeout: let the backlog queue fill up. To produce that, have the server execute all the normal socket setup steps but never call accept() at all, and have the client execute a large number of connect attempts. But if the server platform is Windows, this will produce connection refusals.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • So the connection is refused when the "TCP stack" (sorry, I have little knowledge in this area) fails to connect to the destination port because there is no process listening on that port? And the connection times out when the TCP packets don't even reach the destination / the response doesn't get back in time? – Pig Jul 06 '17 at 16:38
  • @Pig The connection is refused if there isn't a listening process, or the backlog queue is full and the server platform is Windows. l already said that. The connect times out if the peer doesn't respond in time, or at all. I already said that too. – user207421 Jul 07 '17 at 00:18
-1

I've also looked for solutions online, and I came across SlowSocket from the JMeter library, but it seems to be used on the client-side (and I don't think I'll be able to override the client so that it uses SlowSocket).

You can use Sniffy for simulating network latency - it seamlessly integrates with Java TCP stack and doesn't require any changes from application side. See documentation on emulating network issues.

Online demo available at demo.sniffy.io - click on widget in bottom-right corner, go to "Network Connections" tab and set delay to say 1000 milliseconds for en.wikipedia.org. Refresh the browser page and you'll see that it takes 1 seconds more to load the page. javaagent integration is also available for non-web applications.

enter image description here

Disclaimer: I'm the author of Sniffy

bedrin
  • 4,458
  • 32
  • 53
  • But does it simulate a slow connect phase? And if so, how? – user207421 Oct 03 '17 at 01:14
  • Connect phase in TCP basically adds an additional round-trip to the first packet (SYN and SYN-ACK packets do not bring application data; it is only sent with ACK packet). In Java application doesn't have access to IP packets so Sniffy uses some heuristics for adding delays as described here: http://sniffy.io/docs/latest/#_emulating_network_issues ; a specified delay is added to Socket.connect() method on the client side – bedrin Oct 03 '17 at 01:43
  • That's not what was asked for. He wants to see how his *existing* client reacts to a connect timeout, and nothing you've done will cause one. – user207421 Oct 03 '17 at 02:25
  • @EJP Sniffy allows to test how _existing_ clients react to network lags without modifying them. You just need to add -javaagent:sniffy... to the command line arguments. Simulating timeout exceptions after a given delay is also possible. – bedrin Oct 03 '17 at 09:20
  • So, again, tell us exactly how it can produce a connect timeout. The answers you gave above to that question when I asked it before ,twice, are not adequate. Delaying the *client* doesn't cause a connect timeout. Only the server or the network can do that. – user207421 Oct 03 '17 at 10:00
  • @EJP if you run your client with Sniffy and use parameters "Status = OFF; Delay = 1000" Sniffy will throw a java.net.ConnectException after waiting for one second whenever applications invokes Socket.connect(). The code of application is not changed.This is exactly what OP was asking for – bedrin Oct 03 '17 at 11:18