'socket_recv_len_timeout'에 해당되는 글 1건

  1. 2012.02.22 socket_recv_len_timeout

반응형


select() 가 return 하면, timeout 값이 남은 시간으로 변경되기 때문에 그냥 쓰다보면 언젠가는 0 이 되기 때문에 호출되는 즉시 리턴되기 때문에  timeout 값을 설정시에 while문안에넣어줘야 timeout시간이 줄어들지 않는다고 하는데?????? 


int socket_recv_len_timeout(int nSockFd, char *sRecvBuf,int nRecvExpectLen, int nTimeout)
{

    int nRestLen = 0;
    int nRecvLen = 0;
    int nRecvTotalLen = 0;

    int nRet = 0;
    int nReturnValue = 0;

    fd_set fds;
    struct timeval tv;

    nRestLen = nRecvExpectLen;

    /*** set up the file descriptor set ***/
    FD_ZERO(&fds);
    FD_SET(nSockFd, &fds);

    /*** set up the struct timeval for the timeout ***/
    tv.tv_sec = nTimeout;
    tv.tv_usec = 0;

    /*** wait until timeout or data received ***/
    while(1) {

     /*** set up the struct timeval for the timeout ***/
        // tv.tv_sec = nTimeout;
        // tv.tv_usec = 0;
 

        nRet = select(nSockFd+1,&fds,NULL,NULL,&tv);

        if( nRet == 0 ) {  /*** TIMEOUT ***/

            fprintf(stderr, "ERROR_SELECT_TIMEOUT nRet[%d]\n", nRet );

            nReturnValue = (-2);
            break;

        }
        else if( nRet == -1 ) {  /*** ERROR ***/

            if( errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) {

                continue;

            }
            else {

                fprintf(stderr, "ERROR_SELECT_FAIL nRet[%d] errno[%d][%s]\n", nRet, errno, strerror(errno));

                nReturnValue = (-1);
                break;
            }

        }
        else {  /*** 변경사항 발생 ***/

            /*** data must be here, so do a normal recv ***/       
            nRecvLen = recv(nSockFd, &sRecvBuf[nRecvLen], nRestLen, 0);

            if( nRecvLen == 0 ) {  /** 상대편의 접속 해제 ***/

                fprintf(stderr, "0 returned in recv");

                nReturnValue = 0;

                break;

            }
            else if( nRecvLen == -1 ) {  /** 에러 **/

                if( errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK) {

                        continue;

                }
                else {

                    fprintf(stderr, "ERROR_RECV_FAIL nRecvLen[%d]\n", nRecvLen );

                    nReturnValue = (-1);

                    break;
                }

            }
            else {  /** 읽어들인바이트 **/

                nRecvTotalLen = nRecvTotalLen + nRecvLen;
                nRestLen = nRestLen - nRecvLen;

                if( nRestLen == 0 ) {

                    nReturnValue = nRecvTotalLen;
                    break;

                }
               
            }  /* recv > 0 일경우 end */

        }  /* select > 0 일경우 end */

    }  /* while문 end */

}

반응형
Posted by 공간사랑
,