Estoy conectando un proceso de servidor y un proceso de cliente con una conexión TCP, y tengo que detectar
que la conexión física entre las dos máquinas está inactiva. Estoy tratando de hacer esto mediante el mantenimiento de conexión,
disminución de los valores de todo el sistema por defecto a:socket, detectar la conexión se pierde
TCP_KEEPIDLE = 5
TCP_KEEPCNT = 5
TCP_KEEPINTVL = 1
Cuando la conexión se cae (desconecto el cable) solo el servidor en 10 segundos detecta que la conexión se ha perdido, el cliente simplemente cuelga en el envío.
Este es el código de cliente:
#include <iostream>
#include <string.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <errno.h>
#include <netinet/tcp.h>
int main(int argc, char** argv) {
char myVector[1600];
int mySocket = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if (mySocket < 0) {
std::cout << "error creating the socket" << strerror(errno) << std::endl;
::exit(-1);
}
struct sockaddr_in sin;
memset((char *)&sin, 0, sizeof(sin));
sin.sin_addr.s_addr = inet_addr("192.168.21.27");
sin.sin_port = htons(7788);
sin.sin_family = AF_INET;
if (connect(mySocket, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
std::cout << "Error on connection: " << strerror(errno) << std::endl;
::exit(-1);
}
int optval = 1;
socklen_t optlen = sizeof(optval);
/*Enabling keep alive*/
if(setsockopt(mySocket, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) < 0) {
std::cout << "Error setting SO_KEEPALIVE: " << strerror(errno) << std::endl;
}
optval = 5;
optlen = sizeof(optval);
if(setsockopt(mySocket, SOL_TCP, TCP_KEEPIDLE, &optval, optlen) < 0) {
std::cout << "Error setting TCP_KEEPIDLE: " << strerror(errno) << std::endl;
}
optval = 5;
optlen = sizeof(optval);
if(setsockopt(mySocket, SOL_TCP, TCP_KEEPCNT, &optval, optlen) < 0) {
std::cout << "Error setting TCP_KEEPCNT: " << strerror(errno) << std::endl;
}
optval = 1;
optlen = sizeof(optval);
if(setsockopt(mySocket, SOL_TCP, TCP_KEEPINTVL, &optval, optlen) < 0) {
std::cout << "Error setting TCP_KEEPINTVL: " << strerror(errno) << std::endl;
}
for (;;) {
ssize_t myRet= ::send(mySocket,
myVector,
sizeof(myVector),
0);
if (myRet < 0) {
std::cout << "Error: " << strerror(errno) << std::endl;
break;
}
std::cout << myRet << "."; std::cout.flush();
sleep(1);
}
}
Estoy seguro de que me falta algo, pero ¿qué?
Hm. ¿Pero para qué está destinado? – vines
@vines: permite que las conexiones obsoletas de larga duración sean * eventualmente * detectadas y eliminadas, casos en los que la puntualidad no es importante. – caf