zoukankan      html  css  js  c++  java
  • linux网路编程--网络超时检测

    网络超时检测(1)

      设置socket的属性SO_RCVTIMEO

    参考代码:

    struct timeval tv;

    tv..tv_sec=5;//设置5s时间

    tv.tv_usec=0;

    setsockopt(sockfd,SOL_SOCKET,SO_RCVTIMEO,&tv,sizeof(tv));//设置接收超时

    recv/recvfrom

    网络超时检查(2)

      用select检测socket是否‘ready’

    参考代码:

    struct fd_set rdfds;

    struct timeval tv={5,0};

    FD_ZERO(&rdfds);

    FD_SET(sockfd,&rdfds);

    if(selecet(sockfd+1,&rdfs,NULL,NULL,&tv)>0)//socket准备就绪

    {

      recv/recvfrom

    }

    selct-timeout.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <unistd.h>
    #include <string.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <sys/time.h>
    
    #define  N  128
    #define err_log(errlog) do{perror(errlog);exit(1);}while(0)
    
    int main(int argc, const char *argv[])
    {
        fd_set readfds;
        int maxfd;
        int i = 0;
        char buf[N] = {};
        int ret;
    
        int sockfd;
        int acceptfd;
        struct sockaddr_in serveraddr, clientaddr;
        socklen_t addrlen = sizeof(clientaddr);
    
        if(argc < 3)
        {
            fprintf(stderr, "Usage:%s serverip port.
    ", argv[0]);
        }
        if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        {
            err_log("fail to socket");
        }
    
        serveraddr.sin_family = AF_INET;
        serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
        serveraddr.sin_port = htons(atoi(argv[2]));
    
        if(bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0)
        {
            err_log("fail to bind");
        }
    
        if(listen(sockfd, 5) < 0)
        {
            err_log("fail to listen");
        }
    
        FD_ZERO(&readfds);
        maxfd = sockfd;
    
        struct timeval tv;
    
        while(1)
        {
            FD_SET(0, &readfds);
            FD_SET(sockfd, &readfds);
    
            tv.tv_sec = 5;
            tv.tv_usec = 0;
    
            if((ret = select(maxfd+1,&readfds, NULL, NULL,&tv)) < 0)
            {
                err_log("fail to select");
            }
            printf("After select.
    ");
    
            switch(ret)
            {
            case 0:
                printf("Timeout....
    ");
                break;
            default :
                for(i = 0; i < maxfd+1; i++)
                {
                    if(FD_ISSET(i, &readfds))
                    {
                        if(i == 0)
                        {
                            fgets(buf, N, stdin);
                            printf("buf:%s", buf);
                        }
                        if(i == sockfd)
                        {
                            if((acceptfd = accept(sockfd, (struct sockaddr*)&clientaddr, &addrlen)) < 0)
                            {
                                err_log("fail to accept");
                            }
                            printf("%s --> %d --> acceptfd = %d
    ", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port), acceptfd);
                        }
    
                    }
                } // end default
            } // endswitch
        }
        
        return 0;
    }

    网络超时(3)

    设置定时器(timer),捕捉SIGALRM信号

    参考代码:

      void handler(int signo){return;}

    //一旦进程收到这个信号,执行完信号处理函数之后,下一个函数就会直接返回,不阻塞在哪里

    struct sigaction act;

    sigaction(SIGALRM,NULL,&act);

    act.sa_handler=handler

    act.sa_flag&=~SA_RESTART;

    sigaction(SIGALRM,&act,NULL);

    alarm(5)

    if(recv(...)<0)....

    server-alarm.c

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <signal.h>
    #include <errno.h>
    
    #define  err_log(errlog)  do{perror(errlog); exit(1);}while(0)
    #define  N  128
    
    // ./server  192.168.0.196  10000
    
    void handler(int sig)
    {
        printf("timeout....
    ");
    }
    
    int main(int argc, const char *argv[])
    {
        int sockfd;
        int confd;
        struct sockaddr_in  serveraddr, clientaddr;
        char buf[N] = {};
    
        if(argc != 3)
        {
            fprintf(stderr, "Usage:%s serverip port.
    ", argv[0]);
            return -1;
        }
    
        if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        {
            err_log("fail to socket");
        }
    
        printf("sockfd = %d
    ", sockfd);
    
        serveraddr.sin_family = AF_INET;
        serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
        serveraddr.sin_port = htons(atoi(argv[2]));
    
        if(bind(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < 0)
        {
            err_log("fail to bind");
        }
    
        if(listen(sockfd, 10) < 0)
        {
            err_log("fail to listen");
        }
    
        socklen_t addrlen = sizeof(struct sockaddr);
        if((confd = accept(sockfd, (struct sockaddr *)&clientaddr, &addrlen)) < 0)
        {
            err_log("fail to accept");
        }
    
        printf("confd = %d , %s --> %d 
    ", confd , inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
        
        struct sigaction act;
    
        sigaction(SIGALRM, NULL, &act);
    
        act.sa_handler = handler;
        act.sa_flags &= ~SA_RESTART;
    
        sigaction(SIGALRM, &act, NULL);
    
    
        while(1)
        {
            alarm(5);
            if(recv(confd, buf, N, 0) < 0)
            {
                if(errno == 4)
                {
                    printf("errno = %d
    ", errno);
                }
                else
                {
                    err_log("fail to recv");
                }
            }
            printf("From client:%s
    ", buf);
    
        }
    
        close(sockfd);
    
        return 0;
    }

    编译运行,如果客户端5秒不输入,则可以看到

  • 相关阅读:
    duilib中各控件响应的消息类型
    CoInitialize()、CoInitializeEx()和AfxOleInit()区别联系
    Linux下反斜杠号""引发的思考
    人生规划和GTD——“知”、“得”与“合”
    一次失败的面试——IBM电话面试
    Duilib介绍以及各个类的简介
    Linux与Windows中动态链接库的分析与对比
    VC++创建、调用dll的方法步骤
    网络对抗 Exp0 Kali安装 Week1
    2018-2019-1 20165226_20165310_20165315 实验五 通讯协议设计
  • 原文地址:https://www.cnblogs.com/bwbfight/p/9304180.html
Copyright © 2011-2022 走看看