내 TCP 클라이언트가 tcp_keepalive_interval = 10s
, tcp_keepalive_time = 1s
및 tcp_keepalive_probes = 10
의 연결 유지 기능을 구현합니다.보내기가 소켓 보류 중 오류를 감지하지 않습니다.
그러나 연결이 20 초 이상 깨진 후에 send
함수는 오류를 선택하지 않습니다. 이상적으로 keepalive가 활성화 된 상태에서 소켓 보류 오류에 20 초 (keepalive_interval + keepalive_probes*keepalive_time
) E_TIMEDOUT
을 추가해야합니다.
"모두 읽기 (2) 및 (2) 첫째도 데이터를 처리하기 전에 소켓에 대기중인 오류를 검색 할 수 있습니다. 쓰기", this 대답은 말한다으로
연결은 keepalive로 연결을 닫을 때 E_TIMEDOUT
또는 소켓 오류를 선택해야하지만 아래 코드에서는 발생하지 않습니다.
int sockfd = -1;
if ((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
cerr<<"ERROR: Failed to obtain Socket Descriptor!"<<endl;
return -1;
}
//setting keepalive
int optval;
socklen_t optlen = sizeof(optval);
//setting keepalive
optval = 1;
optlen = sizeof(optval);
if(setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) < 0) {
cerr<<"set keepalive failed"<<endl;
return -1;
}
//setting tcp_keepalive_intvl
optval = 10;
optlen = sizeof(optval);
if(setsockopt(sockfd, SOL_TCP, TCP_KEEPINTVL, &optval, optlen) < 0) {
cerr<<"set tcp_keepalive_interval failed"<<endl;
return -1;
}
//setting tcp_keepalive_time
optval = 1;
optlen = sizeof(optval);
if(setsockopt(sockfd, SOL_TCP, TCP_KEEPIDLE, &optval, optlen) < 0) {
cerr<<"set tcp_keepalive_time failed"<<endl;
return -1;
}
//setting tcp_keepalive_probes
optval = 10;
optlen = sizeof(optval);
if(setsockopt(sockfd, SOL_TCP, TCP_KEEPCNT, &optval, optlen) < 0) {
cerr<<"set tcp_keepalive_probe failed"<<endl;
return -1;
}
struct sockaddr_in remote_addr;
remote_addr.sin_family = AF_INET;
remote_addr.sin_port = htons(#port_no);
remote_addr.sin_addr.s_addr = inet_addr(#ip_addr);
memset(&remote_addr.sin_zero, 0, 8);
if (connect(sockfd, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr)) == -1) {
cerr<<"Connect failed with ERRORNO "<<errno<<endl;
return -1;
} else {
cout<<"TcpClient.cpp connected to server"<<endl;
}
while(1) {
char data[20] = "hi hello";
int ret = -1;
if((ret = send(sockfd, data, 20, 0)) < 0) {
cerr<<"TcpClient.cpp:- failed to send_data, ERROR CODE: "<<errno<<endl;
return -1;
} else if (ret == 0) {
cout<<"send returns 0"<<endl;
} else {
cout<<"data sent"<<endl;
}
sleep(1);
}
getchar();
return 0;
이 코드는 gcc 컴파일러가 설치된 Linux 컴퓨터에서 테스트되었습니다. 참고 : recv
과 같은 코드를 사용했지만 E_TIMEDOUT
오류가 발생했습니다.
죄송합니다. 1 초 대신 tcp_keepalive_time을 10 초로 잘못 언급했습니다. 나는 그 질문을 편집했다. 실제로 keepalive 매개 변수에 대한 나의 이해는 정확하지만 내가 누락 된 다른 것이 있습니다. – Kumar