Primeiro, você precisa ter certeza de que o TCP keepalive esteja ativado em seu sistema. Você pode verificar as configurações padrão assim:
# 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
Depois, verifique se você está configurando corretamente no seu código. Deve ser algo como isto:
int optval = 1;
if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval)) < 0) {
perror("setsockopt()");
close(s);
exit(EXIT_FAILURE);
}
No meu sistema, quando uso o código acima para definir SO_KEEPALIVE em ambos os lados, vejo:
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)
E então eu verifiquei com o wireshark que o keepalive NOP
estava sendo enviado.
Mais detalhes podem ser encontrados no TCP Keepalive HOWTO .