Keep-alive options not working on Linux for an outgoing connection

First you need to make sure that TCP keepalive is enabled on your system. You can check the default settings like this:

# sysctl net.ipv4.tcp_keepalive_time net.ipv4.tcp_keepalive_probes net.ipv4.tcp_keepalive_intvl
net.ipv4.tcp_keepalive_time = 7200
net.ipv4.tcp_keepalive_probes = 9
net.ipv4.tcp_keepalive_intvl = 75

Then make sure you're setting it properly in your code. It should look something like this:

int optval = 1;
if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval)) < 0) {
    perror("setsockopt()");
    close(s);
    exit(EXIT_FAILURE);
}

On my system when I use the above code to set SO_KEEPALIVE on both sides I see:

tcp        0      0 127.0.0.1:48591         127.0.0.1:5555          ESTABLISHED keepalive (6958.37/0/0)
tcp        0      0 127.0.0.1:5555          127.0.0.1:48591         ESTABLISHED keepalive (6958.37/0/0)

And then I verified with wireshark that the keepalive NOP was being sent.

More details can be found in the TCP Keepalive HOWTO.