SendN() RecvN()

programming/C_C++ 2017. 12. 19. 18:01
반응형

 

 


/******************************************************************************/
/*
    FUNCTION :
             nRet = SendN(fd, buf, nbytes, &ret_nbytes);

    PARAMS :
             fd - file_descriptor
             buf - send_data_buffer
             nbytes - send_expect_len
             ret_nbytes - real_send_data_len

    RETURN :
             nRet > 0  : send_data_count
             nRet = 0  : error, short data send.
             nRet = -1 : error, fail.
             nRet = -2 : error, Operation would block.

    CHECK  : nRet && nbytes == ret_nbytes check...

*/
/******************************************************************************/

int SendN(int fd, void *buf, size_t nbytes, int *ret_nbytes)
{
    int nRemainLen = 0;
    int nSendCnt = 0;
    int nSendTotalCnt = 0;

    char *ptr = NULL;

    /*** init_value ***/
    *ret_nbytes = 0;

    /*** fd_check ***/
    if(fd < 0) {
        fprintf(stderr, "Invalid fd(%d)\n", fd);

        errno = EBADF;

        return (-1);
    }

    /*** send_data_check ***/
    if(buf == NULL) {
        fprintf(stderr, "Invalid data(%x)\n", buf);

        errno = EINVAL;

        return (-1);
    }

    /*** send_size_check ***/
    if(nbytes <= 0) {
        fprintf(stderr, "Invalid send expect size(%d)\n", nbytes);

        errno = EINVAL;

        return (-1);
    }

    /*** init_value ***/
    nRemainLen = nbytes;
    nSendTotalCnt = 0;

    /*** init_value ***/
    ptr = buf;

    while (nRemainLen > 0) {

        /*** int send(int s, const void *msg, size_t len, int flags); ***/

        nSendCnt = send(fd, ptr, nRemainLen, MSG_NOSIGNAL);

        if (nSendCnt < 0) {

            if (errno == EINTR) {  /* Interrupted system call */

                errno = 0;
                continue;          /* call send() again */

            }
            else if ((errno == EWOULDBLOCK) || (errno == EAGAIN)) {  /* Operation would block. buffer is full */

                *ret_nbytes = nSendTotalCnt;

                fprintf(stderr, "ERROR_FAIL send nSendCnt[%d] errno[%d][%s] nSendTotalCnt[%d]\n", nSendCnt, errno, strerror(errno), nSendTotalCnt);

                return (-2);       /* error */

            }
            else {  /* error_broken */

                *ret_nbytes = nSendTotalCnt;

                fprintf(stderr, "ERROR_FAIL send nSendCnt[%d] errno[%d][%s] nSendTotalCnt[%d]\n", nSendCnt, errno, strerror(errno), nSendTotalCnt);

                return (-1);       /* error */

            }

        }
        else if(nSendCnt == 0) {

            *ret_nbytes = nSendTotalCnt;

            fprintf(stderr, "ERROR_FAIL send nSendCnt[%d] errno[%d][%s] nSendTotalCnt[%d]\n", nSendCnt, errno, strerror(errno), nSendTotalCnt);

            return 0;              /* error */

        }
        else {

            ptr += nSendCnt;

            nRemainLen -= nSendCnt;
            nSendTotalCnt += nSendCnt;

        }

    }

    *ret_nbytes = nSendTotalCnt;

    return nSendTotalCnt;

}

/******************************************************************************/
/*
    FUNCTION :
             nRet = RecvN(fd, buf, nbytes);

    PARAMS :
             fd - file_descriptor
             buf - recv_data_buffer
             nbytes - recv_expect_len

    RETURN :
             nRet > 0  : recv_data_count
             nRet = 0  : eof data recv - short data recv. disconnect.
             nRet = -1 : error, fail.
             nRet = -2 : error, Operation would block.

    CHECK : nRet & nbytes check.... nRet and nbytes difference size enable..
*/
/******************************************************************************/

int RecvN(int fd, void *buf, size_t nbytes)
{
    int nRemainLen = 0;
    int nRecvCnt = 0;
    int nRecvTotalCnt = 0;

    /*** fd_check ***/
    if(fd < 0) {
        fprintf(stderr, "Invalid fd(%d)\n", fd);

        errno = EBADF;

        return (-1);
    }

    /*** send_size_check ***/
    if(nbytes <= 0) {
        fprintf(stderr, "Invalid recv expect size\n", nbytes);

        errno = EINVAL;

        return (-1);
    }

    /*** init_value ***/
    nRemainLen = nbytes;
    nRecvTotalCnt = 0;

    /*** loop_recv ***/
    while (nRemainLen > 0) {

        /*** int recv(int s, void *buf, size_t len, int flags); ***/

        nRecvCnt = recv(fd, buf, nRemainLen, 0);

        if (nRecvCnt < 0) {        /* read error? */

            if (errno == EINTR) {  /* interrupted? */

                errno = 0;
                continue;          /* restart the read */

            }
            else if ((errno == EWOULDBLOCK) || (errno == EAGAIN)) {  /* Operation would block : buffer is full */

                fprintf(stderr, "ERROR_FAIL recv nRecvCnt[%d] errno[%d][%s] nRecvTotalCnt[%d]\n", nRecvCnt, errno, strerror(errno), nRecvTotalCnt);

                return (-2);           /* return error */

            }
            else {  /* error broken */

                fprintf(stderr, "ERROR_FAIL recv nRecvCnt[%d] errno[%d][%s] nRecvTotalCnt[%d]\n", nRecvCnt, errno, strerror(errno), nRecvTotalCnt);

                return (-1);           /* return error */

            }

        }
        else if (nRecvCnt == 0) {  /* EOF? */

            fprintf(stderr, "ERROR_FAIL_EOF recv nRecvCnt[%d] errno[%d][%s] nRecvTotalCnt[%d]\n", nRecvCnt, errno, strerror(errno), nRecvTotalCnt);

            return nRecvTotalCnt;  /* return short count */

        }
        else {

            buf += nRecvCnt;

            nRemainLen -= nRecvCnt;
            nRecvTotalCnt += nRecvCnt;

        }

    }

    return nRecvTotalCnt;

}

/******************************************************************************/

static int Read(int fd, void *buf, size_t nbytes)
{
    int i = 0;
    int r = 0;

    for (i = 0; i < 10; i++) {

        r = read(fd, buf, nbytes);

        if (r < 0) {

            if(errno == EINTR) {

                errno = 0;
                continue;

            }

            break;

        }

        break;

    }

    if (i == 10) {

        fprintf(stderr, "Too Many Interrupted FD[%d]\n", fd);

    }

    return r;

}

/******************************************************************************/

static int Recv(int fd, void *buf, size_t nbytes, int flags)
{
    int i = 0;
    int r = 0;

    for (i = 0; i < 10; i++) {

        r = recv(fd, buf, nbytes, flags);

        if (r < 0) {

            if(errno == EINTR) {

                errno = 0;
                continue;

            }

            break;

        }

        break;

    }

    if (i == 10) {

        fprintf(stderr, "Too Many Interrupted FD[%d]\n", fd);

    }

    return r;

}

/******************************************************************************/

 

 

반응형
Posted by 공간사랑
,