我的TCP客戶端使用tcp_keepalive_interval = 10s
,tcp_keepalive_time = 1s
和tcp_keepalive_probes = 10
實現保持活動功能。發送不是感應套接字掛起錯誤
但是send
函數在連接斷開超過20秒後沒有選擇任何錯誤。理想情況下啓用Keepalive後,應將20s(keepalive_interval + keepalive_probes*keepalive_time
)E_TIMEDOUT
添加到套接字掛起錯誤。
由於this回答說,
「無論是讀取(2)和write(2)第一個嘗試甚至以處理任何數據之前獲取的 插座任何未決的錯誤。」
當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
錯誤整齊。
對不起,錯誤地提到tcp_keepalive_time爲10秒而不是1秒。我編輯了這個問題。其實我對Keepalive參數的理解是正確的,但還有一些我錯過了。 – Kumar