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;
}
--------------------------------------------------------------------------------