码迷,mamicode.com
首页 > 其他好文 > 详细

《UNIX网络编程》之read_timeout实验

时间:2014-10-23 12:00:53      阅读:272      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   os   ar   使用   for   strong   sp   

最近在做项目,需要做一个服务器和客户端的基于TCP的套接口网络编程,由于服务器端返回数据并不是那么的及时,因此,需要在客户端做些延迟,然后才能去读取数据,实验测试结果如下。

 

首先,我们先来看一下我们封装好的一个读延时函数:

#define ERR_EXIT(m)         do         {             perror(m);             exit(EXIT_FAILURE);         }while(0)


/**
 * read timeout - 读超时检测函数,不含读操作
 * @fd: 文件描述符
 * @wait_seconds: 等待超时秒数,如果为0标识不检测超时
 * 成功(未超时)返回0, 失败返回-1, 超时返回-1并且errno = ETIMEOUT
 */
int read_timeout(int fd, unsigned int wait_seconds)
{
    int ret;
    if(wait_seconds > 0)
    {
        fd_set read_fdset;
        struct timeval timeout;

        FD_ZERO(&read_fdset);
        FD_SET(fd, &read_fdset);

        timeout.tv_sec = wait_seconds;
        timeout.tv_usec = 0;

        do
        {
            ret = select(fd + 1, &read_fdset, NULL, NULL, &timeout);
        }while(ret < 0 && errno == EINTR);

        if(ret == 0)//fail
        {
            //time out.
            ret = -1;
            errno = ETIMEDOUT;
        }
        else if(ret == 1)//success
        {
            ret = 0;
        }
    }
    return ret;
}

 

下面,我们介绍如何使用该函数,伪代码如下:

int ret = read_timeout(sockfd, 15);

if(ret == 0)

{

  readnum = read(sockfd, recvbuff, sizeof(recvbuff));

}

else if(ret == -1 && errno == ETIMEDOUT)

{

//time out dealing.

}

 

好,现在继续看我的服务器与客户端程序:

服务器

void str_echo(int sock)
{
    ssize_t n;
    char buff[1024];

    again:
    while( (n = read(sock, buff, sizeof(buff))) > 0)
    {
        fputs(buff, stdout);
        sleep(3);//for testing client read_timeout
        write(sock, buff, n);
    }
    if(n < 0 && errno == EINTR)
    {
        goto again;
    }
    else if(n < 0)
    {
        ERR_EXIT("read");
    }
}

int main()
{
    int listenfd, connfd;
    pid_t childpid;
    socklen_t clilen;
    struct sockaddr_in servaddr, cliaddr;
    
    if( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        ERR_EXIT("socket");
    }

    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(5188);

    if((bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr))) < 0)
    {
        ERR_EXIT("bind");
    }

    if( (listen(listenfd, SOMAXCONN)) < 0)
    {
        ERR_EXIT("listen");
    }

    for(;;)
    {
        clilen = sizeof(cliaddr);
        connfd = accept(listenfd, (struct sockaddr*)&cliaddr, &clilen);
        if(connfd < 0)
        {
            ERR_EXIT("connect");
        }

        if( (childpid = fork()) == 0)
        {
            //child
            close(listenfd);
            str_echo(connfd);
            exit(0);
        }
        else
        {
            //parent
            close(connfd);
        }

    }
}

客户端

void str_cli(int sock)
{
    char sendbuff[1024];
    char recvbuff[1024];

    memset(sendbuff, 0, sizeof(sendbuff));
    memset(recvbuff, 0, sizeof(recvbuff));
    int ret = -1;

    //ssize_t n;
    while(fgets(sendbuff, sizeof(sendbuff), stdin) != NULL)
    {
        write(sock, sendbuff, strlen(sendbuff));    

        ret = read_timeout(sock, 15);
        if(ret == 0)
        {
            read(sock, recvbuff, sizeof(recvbuff));
        }
        else if(ret == -1 && errno == ETIMEDOUT)
        {
            ERR_EXIT("read_timeout");
        }
        fputs(recvbuff, stdout);
    }
}



int main(int argc, char **argv)
{
    
    int sockfd;
    struct sockaddr_in servaddr;
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    servaddr.sin_port = htons(5188);

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd < 0)
    {
        ERR_EXIT("socket");
    }

    if( (connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr))) < 0)
    {
        ERR_EXIT("connect");
    }

    str_cli(sockfd);
    return 0;
}

 

例子一:

服务器延时3s, 客户端read_timeout(socd, 5);结果为:成功

 

《UNIX网络编程》之read_timeout实验

标签:style   blog   color   os   ar   使用   for   strong   sp   

原文地址:http://www.cnblogs.com/wiessharling/p/4045305.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!