반응형

NonBlock Connect() Sample

[출처] NonBlock Recv() Sample|작성자 tius1234


http://blog.junghun.com/220232098095

------------------------------------------------------------------------

#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>

int NonBlockConnect(char *ipaddr, int port, int sec, int usec)
{
    int sock;
    int sbuflen = 4096 * 10;
    int rbuflen = 4096 * 10;

    int val, n, error = 0;

#ifdef _AIX

    socklen_t len;

#else

    int len;

#endif

    fd_set rset, wset;

    struct timeval tv;

 

    struct sockaddr_in serv_addr;

 

    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) return -1;

 

    /*

        참고 사이트 http://www.joinc.co.kr/modules/moniwiki/wiki.php/man/2/setsockopt

     */

    setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char *)&sbuflen, sizeof(sbuflen));

    setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&rbuflen, sizeof(rbuflen));

 

    memset(&serv_addr, 0x00, sizeof(serv_addr));

 

    serv_addr.sin_family = AF_INET;

    serv_addr.sin_port = htons(port);

    serv_addr.sin_addr.s_addr = inet_addr(ipaddr);

 

    /*

        fcntl() 사용방법

        참고 사이트 http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/system_programing/File/Fcntl

     */

    val = fcntl(sock, F_GETFL, 0);

    fcntl(sock, F_SETFL, val | O_NONBLOCK);

 

    /*

        non block connect 를 맺을 경우, 에러를 반환하지만 반환값이 아닌 에러값을 가지고 판단해야 한다.

        에러값이 ECONNREFUSED와 같은 계열이 아닌 EINPROGRESS 일 경우에는 접속에러가 아닌 접속을 맺기 위해 시도중임을 알수가 있다.

     */

    n = connect(sock, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr_in));

    if (n < 0)

    {

        if (errno != EINPROGRESS)

        {

            close(sock);

            return -1;

        }

    }

    else if (n == 0)

    {

        goto done;

    }

 

    FD_ZERO(&rset);

    FD_SET(sock, &rset);

    wset = rset;

    tv.tv_sec = sec;

    tv.tv_usec = usec;

 

    if ((n = select(sock + 1, &rset, &wset, NULL, &tv)) == 0)

    {

        errno = ETIMEDOUT;

        close(sock);

        return -2;

    }

    if (FD_ISSET(sock, &rset) || FD_ISSET(sock, &wset))

    {

        len = sizeof(error);

        if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *)&error, &len) < 0)

        {

            close(sock);

            return -3;

        }

    }

    else

    {

        close(sock);

        return 0;

    }

 

done:

    fcntl(sock, F_SETFL, val);

 

    if (error)

    {

        errno = error;

        close(sock);

        return -4;

    }

    return sock;

}
--------------------------------------------------------------------------------

 

 


NonBlock Recv() Sample

[출처] NonBlock Recv() Sample|작성자 tius1234


http://blog.junghun.com/220232097293

--------------------------------------------------------------------------------
#include <sys/socket.h>

#include <netinet/in.h>

#include <fcntl.h>

 

int    NonBlockRecv(int sock, char    *recvbuf, int wait_sec,    int    wait_usec)

{

    int    MAX_BUF_SZ = 4096*10;

    int    len, n,    error =    0;

 

    fd_set fd;

    struct timeval tv;

 

    FD_ZERO(&fd);

    FD_SET(sock, &fd);

    tv.tv_sec =    wait_sec;

    tv.tv_usec = wait_usec;

 

    if ((n = select(sock + 1, &fd, NULL, NULL, &tv)) ==    0)

    {

        errno =    ETIMEDOUT;

        return -1;

    }

 

    if (FD_ISSET(sock, &fd))

    {

        while(1)

        {

            len    = recv(sock, recvbuf, MAX_BUF_SZ, 0);

            if (len    < 0) {

                if(    errno == EINTR )

                    continue;

                return(-1*errno);

            }

 

            if (!len)

                 return(-2);

            else

                break;

        }

 

        //printf("[recv_len    : %d] [recv_buf    : %.*s]\n",    len, len, recvbuf);

    }

 

    if (error)

    {

        errno =    error;

        return -3;

    }

 

    return len;

}
--------------------------------------------------------------------------------

 

반응형
Posted by 공간사랑
,