首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

求问linux下keepalive断开连接时怎么返回异常码

2013-09-05 
求问linux下keepalive断开连接时如何返回错误码本帖最后由 yxl2725130 于 2013-08-28 15:44:54 编辑如题,

求问linux下keepalive断开连接时如何返回错误码
本帖最后由 yxl2725130 于 2013-08-28 15:44:54 编辑
如题,之前看到资料说可以通过recv()返回错误码,但是断开网线后可以实现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");
}
                    }
                }
            }
        }
    }
}

c select keepalive
[解决办法]
没看懂问题。
------解决方案--------------------


断开网线后可以实现keepalive机制? 这是啥意思?

keepalive 是长链接的报活机制的!
客户端或者服务端定时向对端发送的一条指令确保这条链路是可用的!有效的!
[解决办法]
自己定义协议。

热点排行