socket connect 함수의 처리시간의 조정 방법은 없을 까요 ?
글쓴이: shpark05 작성 일시: 화, 2004/10/12 - 10:43오전
프로그래밍 QnA
connect 함수 사용시 , 상대측 서버의 응답이 없을 경우에
이를 빨리 감지하여 접속을 단절 하고 싶습니다.
1-2초 정도 시간만 주려고 합니다만, 특별한 방법이 없을까 궁금합니다.
소켓설정에서 linger 는 사용중입니다.
약 10초정도 텀이 생기는것 같습니다.
‹ Hard Disk S.M.A.R.T. 기능에 대해서..[완료]popen 함수로 스크립트를 호출 했습니다. ›.
man setsockopt여기서 SO_RCVTIMEO 이부분을 보시면
글쓴이: 서지훈 작성 일시: 화, 2004/10/12 - 11:16오전
man setsockopt
여기서 SO_RCVTIMEO 이부분을 보시면은 원하는 대답이 될듯 하네요.
<어떠한 역경에도 굴하징 낳는 '하양 지훈'>
—
#include <com.h> <C2H5OH.h> <woman.h>
do { if (com) hacking(); if (money) drinking(); if (women) loving(); } while (1);
.
» 답글
스티븐스아저씨 책보고 약간 수정한거
글쓴이: bw001730 작성 일시: 화, 2004/10/12 - 11:24오전
저도 맨날 여기서 질문만 올리는데
모처럼 아는거 나와서 답변을 적어봅니다.
혹시나 틀린거 있으면 답변주시길..
제가 회사에서 만든것인데요
아니..만들었다기 보다는 스티븐스 아저씨책에서 약간 수정한거
아니.....거의그대로 가져다 -.- 썼어요
connect() 함수에 타이머 걸기가 어렵게 느껴지는 이유는
connect() 함수가 블럭킹되는 함수이기 때문입니다.
이를 해결하기 위해서...
connect() 함수로 연결을 기다리기 전에
소켓을 non-block 모드로 설정한후에
connect() 호출합니다. 그러면 connect()가 즉시 리턴하거든요, 연결이 되든 안되든...
그후 select()를 호출하면 됩니다.
non-block 소켓이 연결되거나, 타임아웃이 되면 select() 함수가 리턴합니다.
select() 함수의 리턴값을 보고, 연결되었는지 타임아웃인지를 확인할수 있습니다.
그니깐 순서가..
1. 소켓을 non-block 으로 설정
2. connect() 호출--- 즉시 리턴
3. select()로 타임아웃을 기다림
4. 소켓의 non-block 을 해제
머 이런순으로 되겠죠
책보면 다나오는 것이지만... 혹시나 고수님들의 딴지를 기대하며
제가 작성한 소스를 올려봅니다.
님이 궁금해하시는 소스는 connect_nonb() 부분일겁니다.
int tcp_connect_timeo(const char *hostname, const char *service,int nsec)
{
struct addrinfo hints, *res, *ressave;
int sock,n;
bzero(&hints, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if( (n=getaddrinfo(hostname,service,&hints,&res)) != 0)
return -1;
ressave = res;
do
{
struct sockaddr_in *ts;
sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if(sock < 0)
continue;
ts = (struct sockaddr_in *) res->ai_addr;
if(connect_nonb(sock, (struct sockaddr *)res->ai_addr, res->ai_addrlen,nsec) == 0)
break;
close(sock);
}while( (res=res->ai_next) !=NULL);
if( res == NULL)
return -1;
freeaddrinfo(ressave);
return sock;
}
int connect_nonb(int sockfd, const struct sockaddr *saptr, int salen, int nsec)
{
int flags, n, error;
socklen_t len;
fd_set rset, wset;
struct timeval tval;
flags = fcntl(sockfd, F_GETFL, 0);
fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
error = 0;
if ( (n = connect(sockfd, (struct sockaddr *) saptr, salen)) < 0)
if (errno != EINPROGRESS)
return(-1);
/* Do whatever we want while the connect is taking place. */
if (n == 0)
goto done; /* connect completed immediately */
FD_ZERO(&rset);
FD_SET(sockfd, &rset);
wset = rset;
tval.tv_sec = nsec;
tval.tv_usec = 0;
if ( (n = select(sockfd+1, &rset, &wset, NULL,
nsec ? &tval : NULL)) == 0) {
close(sockfd); /* timeout */
errno = ETIMEDOUT;
return(-1);
}
if (FD_ISSET(sockfd, &rset) || FD_ISSET(sockfd, &wset)) {
len = sizeof(error);
if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0)
return(-1); /* Solaris pending error */
} else
err_quit("select error: sockfd not set");
done:
fcntl(sockfd, F_SETFL, flags); /* restore file status flags */
if (error) {
close(sockfd); /* just in case */
errno = error;
return(-1);
}
return(0);
}
» 답글
시원하네요.
글쓴이: mahapunch 작성 일시: 금, 2008/02/15 - 5:15오후
정말 가려운데 손이 안닿는 곳을
아주 시원하게 긁어 주는 글이었습니다.
감사해요~
better tommrow than yesterday - cs. shin.
—
better tommrow than yesterday - cs. shin.
.
» 답글
SIGALRM으로 튕겨내는건 어떤가요? alarm() 쓰면 됩니다.
글쓴이: Necromancer 작성 일시: 화, 2004/10/12 - 11:41오전
SIGALRM으로 튕겨내는건 어떤가요? alarm() 쓰면 됩니다.
스레드 안쓴다면 가장 간단한 방법이죠.
—
Written By the Black Knight of Destruction
.
» 답글
Re: 스티븐스아저씨 책보고 약간 수정한거
글쓴이: yielding 작성 일시: 화, 2004/10/12 - 1:46오후
bw001730 wrote:
제가 회사에서 만든것인데요
아니..만들었다기 보다는 스티븐스 아저씨책에서 약간 수정한거
아니.....거의그대로 가져다 -.- 썼어요
:D
—
Life rushes on, we are distracted
.
» 답글
bw001730님의 답변과 흑기사님의 답변이 connection time
글쓴이: jinyeong 작성 일시: 화, 2004/10/12 - 1:48오후
bw001730님의 답변과 흑기사님의 답변이 connection timeout을 주는 방법입니다.
이는 아마도 unp에도 나와 있을테고,
socket faq를 보셔도 두가지 답변이 함께 기술되어 있습니다.
alarm을 쓰실 수 있는 경우라면 그게 간단한 해결책이 되겠지요.
—
I thought what I'd do was,
I'd pretend I was one of those deaf-mutes.. or should I?
.
» 답글
alarm(5);connect(...);alarm(0);알
글쓴이: nthroot 작성 일시: 화, 2004/10/12 - 5:08오후
alarm(5);
connect(...);
alarm(0);
알람을 5초로 걸고 5초안에 alarm(0)을 통해서 해제를 못하게 되면
connect() 함수 블럭 상태에서 자동으로 알람핸들러 함수가 호출되게 됩니다.
connect()는 인터럽트 되게 되고 알람핸들러에서 적당한 처리를 해주시거나
그냥 두시면 됩니다.
정상적으로 connect()에서 연결이 되면 alarm(0)으로 해제가 됩니다.
유닉스 관련 서적에서 시스템콜 alarm 을 보시면 예제들이 있을거에요.
—
------식은이 처------
길이 끝나는 저기엔 아무 것도 없어요. 희망이고 나발이고 아무 것도 없어.
.
» 답글
감사드립니다. 글을 늦게 확인했습니다 ^^;:)
글쓴이: shpark05 작성 일시: 수, 2004/11/24 - 5:48오전
감사드립니다. 글을 늦게 확인했습니다 ^^;
:)
» 답글