/******************************************************************************/
int SocketConnectTimeout(char *sIpAddr, int nPort, int nConnectTimeout)
{
int nRet;
int nSockFd;
struct sockaddr_in serv_addr;
int nSockOpt=1;
int nReUseOpt=1;
struct linger lin;
nSockFd = socket(AF_INET, SOCK_STREAM, 0);
if( nSockFd < 0 ) {
fprintf(stderr, "ERROR_SOCKET_FAIL\n");
return -1;
}
memset((char *) &serv_addr, 0x00, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr(sIpAddr); /*** 숫자와 점으로 구성된 IP주소를 unsigned long 변수에 집어 넣어 준다 ***/
serv_addr.sin_port = htons(nPort); /*** "Host to Network Short" ***/
/*** 타임아웃알림시그널 - 아래의 4라인을 signal(SIGALRM,alrm_handler); 로 표현가능 **/
alrm_action.sa_handler = alrm_handler;
alrm_action.sa_flags = 0; /* don't restart */
sigemptyset(&alrm_action.sa_mask);
sigaction(SIGALRM, &alrm_action, NULL);
alarm(nConnectTimeout);
nRet = connect(nSockFd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
if( nRet < 0 ) {
fprintf(stderr, "ERROR_CONNECT_FAIL\n");
alarm(0);
close(nSockFd);
return -1;
}
alarm(0);
/*** 이부분에서 SOCKET옵션을 설정해줄수 있다 ***/
if (setsockopt(nSockFd, SOL_SOCKET, SO_KEEPALIVE, (char*)&nSockOpt, sizeof(nSockOpt)) < 0) {
fprintf(stderr,"ERROR_setsockopt(SO_KEEPALIVE)_FAIL errno[%d][%s]\n", errno, strerror(errno));
return -1;
}
if (setsockopt(nSockFd, SOL_SOCKET, SO_REUSEADDR, (char*)&nReUseOpt, sizeof(nReUseOpt)) < 0) {
fprintf(stderr,"ERROR_setsockopt(SO_REUSEADDR)_FAIL errno[%d][%s]\n", errno, strerror(errno));
return -1;
}
lin.l_onoff = 1;
lin.l_linger = 0;
if (setsockopt(nSockFd, SOL_SOCKET, SO_LINGER, (char*)&lin, sizeof(lin)) < 0) {
fprintf(stderr,"ERROR_setsockopt(SO_LINGER)_FAIL errno[%d][%s]\n", errno, strerror(errno));
return -1;
}
return nSockFd;
}
/******************************************************************************/
void alrm_handler(int signo)
{
fprintf(stderr, "socket_connect_alrm_handler occur...\n");
return;
}
/******************************************************************************/