求问linux下keepalive断开连接时如何返回错误码
本帖最后由 yxl2725130 于 2013-08-28 15:44:54 编辑
如题,之前看到资料说可以通过recv()返回错误码,但是断开网线后可以实现keepalive机制,却没有任何错误码返回,希望高人指点
c select keepalive
#include <netinet/tcp.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
int main()
{
int server_sockfd, client_sockfd;
int server_len, client_len;
struct sockaddr_in server_address;
struct sockaddr_in client_address;
int result,maxfds;
fd_set readfds, testfds;
int optval=1;
int keepalive_idle_client = 10;//开始首次KeepAlive探测前的TCP空闭时间
int keepalive_interval_client = 5;//两次KeepAlive探测间的时间间隔
int keepalive_probes_client = 3;//判定断开前的KeepAlive探测次数
if((server_sockfd = socket(AF_INET, SOCK_STREAM, 0))<0)
{
perror("socket fail:");
}
maxfds=server_sockfd;
printf("server_sockfd is %d\n",server_sockfd);
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = htonl(INADDR_ANY);
server_address.sin_port = 9734;
server_len = sizeof(server_address);
int flags=fcntl(server_sockfd,F_GETFL,0);
fcntl(server_sockfd,F_SETFL,O_NONBLOCK|flags);
if(bind(server_sockfd, (struct sockaddr *)&server_address, server_len)<0)
{
perror("bind fail");
}
if(listen(server_sockfd, 5)<0)
{
perror("listen fail");
}
FD_ZERO(&readfds);
FD_SET(server_sockfd, &readfds);
while(1)
{
char ch;
int fd;
int nread;
testfds = readfds;
printf("server waiting\n");
result = select(maxfds+1, &testfds, (fd_set *)0, (fd_set *)0, (struct timeval *) 0);
printf("result = %d\n",result);
if(result < 1)
{
perror("server5");
exit(1);
}
for(fd = 0; fd < maxfds+1; fd++)
{
if(FD_ISSET(fd,&testfds))
{
if(fd == server_sockfd)
{
client_len = sizeof(client_address);
if((client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_address, &client_len))<0)
{
perror("accept fail");
}
if(setsockopt(client_sockfd, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval)) < 0)
{
perror("setsockopt()");
close(client_sockfd);
}
printf("SO_KEEPALIVE set on socket\n");
if(setsockopt(client_sockfd,SOL_TCP,TCP_KEEPIDLE,(void *)&keepalive_idle_client,sizeof(keepalive_idle_client)) == -1)
{
perror("setsockopt keepalive_idle failed:");
}
if(setsockopt(client_sockfd,SOL_TCP,TCP_KEEPINTVL,(void *)&keepalive_interval_client,sizeof(keepalive_interval_client)) == -1)
{
perror("setsockopt keepalive_interval failed:");
}
if(setsockopt(client_sockfd,SOL_TCP,TCP_KEEPCNT,(void *)&keepalive_probes_client,sizeof(keepalive_probes_client)) == -1)
{
perror("setsockopt keepalive_probes failed:");
}
maxfds=(maxfds>client_sockfd)?maxfds:client_sockfd;
FD_SET(client_sockfd, &readfds);
printf("adding client on fd %d\n", client_sockfd);
}
else
{
if(ioctl(fd, FIONREAD, &nread)<0)
{
perror("ioctl fail");
}
if(nread == 0)
{
close(fd);
FD_CLR(fd, &readfds);
printf("removing client on fd %d\n", fd);
}
else
{
if(recv(fd, &ch, 1, 0)<1)
{
perror("recv fail:");
printf("@@@@@@@@@@@@@@@@@@@@@\n");
}
// sleep(3);
printf("serving client on fd %d\n", fd);
printf("recving char from client:%c\n",ch);
ch++;
if(send(fd, &ch, 1, 0)<0)
{
perror("send fail");
}
}
}
}
}
}
}