Hot questions for Using Transmission Control Protocol in apache

Question:

I have http request that takes too much time to be processed by the server (about 5 minutes). Because connection becomes idle for 5 minutes, proxy server shutdowns the connection. I'm trying to use TCP Keep-Alive in Apache DefaultHttpClient to make connection be alive for a long time (Not confuse TCP Keep-Alive with HTTP Keep-Alive that simply doesn't closes connection after response is sent).

Apache http core has following parameter SO_KEEPALIVE: http://hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/org/apache/http/params/CoreConnectionPNames.html#SO_KEEPALIVE. However, due to DefaultHttpClient javadocs I can't customize client's behavior with that parameter: https://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/impl/client/DefaultHttpClient.html.

I did this, however, seems it doesn't work:

HttpClient client = getHttpClient();
client.getParams().setParameter(CoreConnectionPNames.SO_KEEPALIVE, true);

Do you know how to make DefaultHttpClient use TCP Keep-Alive strategy?


Answer:

To make it work I needed to set keepalive timeouts. But they can be set only on OS level, not in Java code. As I know, it's not possible to set keepalive timeouts in Java code.

Here is how I set them on Linux:

sudo sysctl -w net.ipv4.tcp_keepalive_time=60
sudo sysctl -w net.ipv4.tcp_keepalive_intvl=60
sudo sysctl -w net.ipv4.tcp_keepalive_probes=10

Value is amount of seconds.

Question:

I have a server setup using MINA version 2. I don't have much experience with sockets and tcp.

The problem is if I make a connection to my server, and then unplug my internet and close the connection, (Server doesn't get notification of the connection being closed) the server will forever think that my connection is still active and valid.

The server will continue to send messages to my connection, and doesn't throw any exceptions even though there is nothing on my computer binded to the local port.

How can I test that the connection still exists?

I've tried running MINA logging in debug mode, and logging the

 IoSession.isConnected() IoSession.isActive IoSession.isClosing

They always return true, true, false. Also, in debug mode, there was no useful information stating that the connection was lost. It just logged the regular "sent message" stuff, as if there was nothing wrong.

From using Flash actionscript, I have had experiences where flash will throw errors that it's operating on an invalid socket. That leads me to believe that it's saying the socket on the server is no longer valid for the connection. So in other words if flash can detect invalid sockets, a Java server should be able to detect it too correct?

If there is truly no way to detect dead connections, I can always setup a connection keep alive routine where the client is constantly sending an "I'm here" message to the server, and the server closes sessions that havent had an incoming message for a period of seconds.


EDIT: After learning that "sockets" are private and never shared over the network I managed to find better results for my issue and I found this SO thread.

Java socket API: How to tell if a connection has been closed?

Unfortunately

IOException 'Connection reset by peer' Doesn't occur when I write to the IoSession in MINA.


Edit:

Is there any way at all in Java to detect when an ACK to a TCP packet was not received after sending a packet? An ACK Timeout?


Edit:

Yet apparantly, my computer should send a RST to the server? According to this answer. https://stackoverflow.com/a/1434592/4425643 But that seems like a bad way of port scanning. Is this how port scanning works? Port scanners send data to a port and the victim's service responds with a RST? Sorry I think I need a new question for all this. But it's odd that MINA doesn't throw connection reset by peer when it sends data. So then my computer doesn't send a RST.


Answer:

The concept of socket or connection in Internet protocols is an illusion. It's a convenient abstraction that is provided to you by the operating system and the TCP stack, but in reality, it's all fake.

Under the hood, everything on the Internet takes the form of individual packets.

From the perspective of a computer sending packets to another computer, there is no built-in way to know whether that computer is actually receiving the packets, unless that computer (or some other computer in between, like a router) tells you that the packets were, or were not, received.

From the perspective of a computer expecting to receive packets from another computer, there is no way to know in advance whether any packets are coming, will ever come, or in what order -- until they actually arrive. And once they arrive, just the fact that you received one packet does not mean you'll receive any more in the future.

That's why I say connections or sockets are an illusion. The way that the operating system determines whether a connection is "alive" or not, is simply by waiting an arbitrary amount of time. After that amount of time -- called a timeout -- if one side of the TCP connection doesn't hear back from the other side, it will just assume that the other end has been disconnected, and arbitrarily set the connection status to "closed", "dead" or "terminated" ("timed out").

So:

  • Your server has no clue that you've pulled the plug on your Internet connection. It has no way of knowing that.
  • Your server's TCP stack has been configured a certain way to wait an arbitrary amount of time before "giving up" on the other end if no response is received. If this timeout is set to a very large period of time, it may appear to you that your server is hanging on to connections that are no longer valid. If this bothers you, you should look into ways to decrease the timeout interval.

Analogy: If you are on a phone call with someone, and there's a very real risk of them being hurt or killed, and you are talking to them and getting them to answer, and then the phone suddenly goes dead..... Well, how long do you wait? At what point do you assume the other person has been hurt or killed? If you wait a couple milliseconds, in most cases that's too short of a "timeout", because the other person could just be listening and thinking of how to respond. If you wait for 50 years, the person might be long dead by then. So you have to set a reasonable timeout value that makes sense.

Question:

I have installed hadoop on two node cluster- Node1 and Node2. Node1 is master and Node2 is slave. Node2's datanode and Nodemanager are not able to connect Namenode and Resourcemanager on Node1 respectively. However Node1's datanode and Nodemanager are not able to connect Namenode and Resourcemanager on Node1.


Node1: jps 18083 ResourceManager 18572 Jps 18207 NodeManager 17621 DataNode 17827 SecondaryNameNode 17478 NameNode

Node2: jps 1548 DataNode


For Node2 NodeManger is giving below exception:

FATAL org.apache.hadoop.yarn.server.nodemanager.NodeManager: Error starting NodeManager org.apache.hadoop.yarn.exceptions.YarnRuntimeException: java.net.NoRouteToHostException: No Route to Host from node2/10.222.188.172 to node1:8031 failed on socket timeout exception: java.net.NoRouteToHostException: No route to host; For more details see: http://wiki.apache.org/hadoop/NoRouteToHost

For Node2 DataNode is giving below error:

WARN org.apache.hadoop.hdfs.server.datanode.DataNode: Problem connecting to server: node1/10.222.188.107:9000 2015-06-19 08:42:54,786 INFO org.apache.hadoop.ipc.Client: Retrying connect to server: node1/10.222.188.107:9000. Already tried 0 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10, sleepTime=1000 MILLISECONDS)


Output of netstat -nlp | grep 9000 on node1

tcp 0 0 10.222.188.107:9000 0.0.0.0: LISTEN 17478/java*

output of netstat -nlp | grep 8031 on node1:

tcp 0 0 10.222.188.107:8031 0.0.0.0: LISTEN 18083/java*


etc/hosts file node1 & node2:

127.0.0.1 localhost

10.222.188.106 master

10.222.188.107 node1

10.222.188.172 node2


Answer:

I figured the issue. In iptables rules tcp connection were blocked. I flushed iptables rules using below command and issue is resolved.

sudo iptables -F

Question:

I need the time from a NTP server.

I tied this:

  TimeUDPClient client = new TimeUDPClient();
  try {
        client.open();
        client.setSoTimeout(10000);
        client.getTime(InetAddress.getByName(host));
        client.close();
  } catch (IOException exp) {
        System.out.println("NTP connection error");
        exp.printStackTrace();
        return;
  }

After a 10 Sekonds I get this exception:

java.net.SocketTimeoutException: Receive timed out at java.net.PlainDatagramSocketImpl.receive0(Native Method) at java.net.AbstractPlainDatagramSocketImpl.receive(AbstractPlainDatagramSocketImpl.java:143) at java.net.DatagramSocket.receive(DatagramSocket.java:812) at org.apache.commons.net.time.TimeUDPClient.getTime(TimeUDPClient.java:84) at org.apache.commons.net.time.TimeUDPClient.getTime(TimeUDPClient.java:98) at de.modusoft.opt.viewer.TimeSyncThread.run(TimeSyncThread.java:34) at java.lang.Thread.run(Thread.java:748)

I also tried this:

    TimeTCPClient client = new TimeTCPClient();
    client.setConnectTimeout(10000);
    try {
        client.connect(host);
        Date ntpDate = client.getDate();
        client.disconnect();
        System.out.println("ntpDate = " + ntpDate);
    } catch (IOException exp) {
        System.out.println("NTP connection error");
        exp.printStackTrace();
        return;
    }

And got also a Timout exception.

java.net.SocketTimeoutException: connect timed out at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) at java.net.Socket.connect(Socket.java:589) at org.apache.commons.net.SocketClient.connect(SocketClient.java:182) at org.apache.commons.net.SocketClient.connect(SocketClient.java:203) at org.apache.commons.net.SocketClient.connect(SocketClient.java:296) at de.modusoft.opt.viewer.TimeSyncThread.run(TimeSyncThread.java:29) at java.lang.Thread.run(Thread.java:748)

host is a String and a tried "0.de.pool.ntp.org", "ntp.xs4all.nl".

Thanks for your help.


Answer:

If you need the time from an NTP server, you need to use the NTP protocol. The TimeUDPClient and TimeTCPClient classes use the Time Protocol, not NTP.