ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

非阻塞读和写:str_cli函数(修订版)

2019-04-26 20:49:21  阅读:246  来源: 互联网

标签:FILENO cli toiptr friptr read 修订版 FD str sockfd


void str_cli(FILE *fp, int sockfd)
{
    int        maxfdp1, val, stdineof;
    ssize_t    n, nwritten;
    fd_set     rset, wset;
    char       to[MAXLINE], fr[MAXLINE];
    char       *toiptr, *tooptr, *friptr, *froptr;

    val = fcntl(sockfd, F_GETFL, 0);
    fcntl(sockfd, F_SETFL, val | O_NONBLOCK);

    val = fcntl(STDIN_FILENO, F_GETFL, 0);
    fcntl(STDIN_FILENO, F_SETFL, val | O_NONBLOCK);

    val = fcntl(STDOUT_FILENO, F_GETFL, 0);
    fcntl(STDOUT_FILENO, F_SETFL, val | O_NONBLOCK);

    toiptr = tooptr = to;    /* initialize buffer pointers */
    friptr = froptr = fr;
    stdineof = 0;

    maxfdp1 = max(max(STDIN_FILENO, STDOUT_FILENO), sockfd) + 1;
    for ( ; ; ) {
        FD_ZERO(&rset);
        FD_ZERO(&wset);
        if (stdineof == 0 && toiptr < &to[MAXLINE]) 
            FD_SET(STDIN_FILENO, &rset);    /* read from stdin */
        if (friptr < &fr[MAXLINE])
            FD_SET(sockfd, &rset);          /* read from socket */
        if (tooptr != toiptr)
            FD_SET(sockfd, &wset);          /* data to write to socket */
        if (froptr != friptr)
            FD_SET(STDOUT_FILENO, &wset);   /* data to write to stdout */

        select(maxfdp1, &rset, &wset, NULL, NULL);

        if (FD_ISSET(STDIN_FILENO, &rset)) {
            if ( (n = read(STDIN_FILENO, toiptr, &to[MAXLINE] - toiptr)) < 0) {
                if (errno != EWOULDBLOCK)
                    err_sys("read error on stdin");
            } else if (n == 0) {
fprintf(stderr, "%s: EOF on stdin\n", gf_time()); stdineof = 1; /* all done with stdin */ if (tooptr == toiptr) shutdown(sockfd, SHUT_WR); /* send FIN */        } else { fprintf(stderr, "%s: read %d bytes from stdin\n", gf_time(), n); toiptr += n; /* # just read */ FD_SET(sockfd, &wset); /* try and write to socket below */ } } if (FD_ISSET(sockfd, &rset)) { if ( (n = read(sockfd, friptr, &fr[MAXLINE] - friptr)) < 0) { if (errno != EWOULDBLOCK) err_sys("read error on socket");        } else if (n == 0) { fprintf(stderr, "%s: EOF on socket\n", gf_time()); if (stdineof) return; /* normal termination */ else err_quit("str_cli: server terminated prematurely"); } else { fprintf(stderr, "%s: read %d bytes from socket\n", gf_time(), n); friptr += n; /* # just read */ FD_SET(STDOUT_FILENO, &wset); /* try and write below */ } }

if (FD_ISSET(STDOUT_FILENO, &wset) && ( (n = friptr - froptr) > 0)) { if ( (nwritten = write(STDOUT_FILENO, froptr, n)) < 0) { if (errno != EWOULDBLOCK) err_sys("write error to stdout");        } else { fprintf(stderr, "%s: wrote %d bytes to stdout\n", gf_time(), nwritten); froptr += nwritten; /* # just written */ if (froptr == friptr) froptr = friptr = fr; /* back to beginning of buffer */ } } if (FD_ISSET(sockfd, &wset) && ( (n = toiptr - tooptr) > 0)) { if ( (nwritten = write(sockfd, tooptr, n)) < 0) { if (errno != EWOULDBLOCK) err_sys("write error to socket"); } else { fprintf(stderr, "%s: wrote %d bytes to socket\n", gf_time(), nwritten); tooptr += nwritten;      /* # just written */ if (tooptr == toiptr) { toiptr = tooptr = to; /* back to beginning of buffer */ if (stdineof) shutdown(sockfd, SHUT_WR); /* send FIN */ } } } } }
char  *gf_time(void)
{
    struct timeval tv;
    time_t         t;
    static char    str[30];
    char           *ptr;

    if (gettimeofday(&tv, NULL) < 0)
        err_sys("gettimeofday error");

    t = tv.tv_sec;    /* POSIX says tv.tv_sec is time_t; some BSDs don't agree. */
    ptr = ctime(&t);
    strcpy(str, &ptr[11]);
    /* Fri Sep 13 00:00:00 1986\n\0 */
    /* 0123456789012345678901234 5  */
    snprintf(str+8, sizeof(str)-8, ".%06ld", tv.tv_usec);

    return(str);
}

 

标签:FILENO,cli,toiptr,friptr,read,修订版,FD,str,sockfd
来源: https://www.cnblogs.com/soldierback/p/10776459.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有