select함수의 TimeOut 질문입니다.

Dr_stein의 이미지

제가 리눅스에서 socket을 사용하기위해 select 함수를 테스트 해보니...
TimeOut이 연결을 지속하는 총 시간을 의미하는듯 하네여...

제가 원하는건 일정 시간동안 아무일도 일어나지 않을때 연결을 끊는것을
원하는데요....

어떻게 해결해야 할지 알려주십시요.

pynoos의 이미지

select의 return 값이 0 이면 time out 입니다.

select 된 갯수 0 개 라는 뜻이겠지요..

return 값이 -1 이 아니라면 timeout입니다.

Dr_stein의 이미지

select 된 갯수 0 개 라는 뜻이겠지요.. <== 이말씀은...
결국 제가 원하는거 같은데... -_-;;

그렇게 되지를 않고.. 그냥 TimeOut에 정해준 시간이 지나면...자동으로 연결을
종료해 버리는것 같아서 질문 드리는 겁니다.

앞마당 먹고 시작한 저그의 8할은 뮤탈 테크를 먼저 탄다. 하지만 나머지 2할때문에 항상 스켄이 모자란다. - _-;

pynoos의 이미지

뭔가 잘못 보신 듯 합니다만....

select 문에 들어가는 time out 값은 select 대기 시간이 맞습니다.

연결을 끊는 부분은 다른 곳에 있을 것입니다.

Dr_stein의 이미지

네.. 다시한번 살펴보겠습니다. ^^;

근데 같은 코드를 유닉스에서 실행할때는 잘 되던것이...
리눅에서 돌리니 그 부분에서 문제가 생기길래.. 제가 모르는 어떤 셋팅이 필요한가 싶어서 질문 드린겁니다. man page에도 그렇게 나온거 같은데
이상하네여 -_-;;
어쨌든 답변 감사합니다.

앞마당 먹고 시작한 저그의 8할은 뮤탈 테크를 먼저 탄다. 하지만 나머지 2할때문에 항상 스켄이 모자란다. - _-;

zikpreed의 이미지

유닉스에서는 잘 되던 것이...
리눅스에서는 안 될 수 있습니다.

select() 호출시 마지막 파라미터인 struct timeval 값이 리눅스에서는 남은 타임아웃 값으로 업데이트 되는데, 유닉스에서는 그렇지 않습니다.
Stevens 의 Unix Network Program 2nd Ed.의 p.150에 나오는 함수 원형에는 마지막 파라미터 앞에 const가 있습니다.

Linux man 페이지에는 없구요.

때문에 유닉스에서는 select()를 매번 호출할 때마다 struct timeval 값을 재설정하지 않아도 되지만, 리눅스에서 select()를 매번 호출할 때마다 struct timeval 값을 다시 리셋해 주어야 합니다.

- 10년 가까이 된 질문에 뭐하는 짓인지...
나중에 제가 다시 와서 볼지도 몰라서... -_-;

frowt의 이미지

제 생각에는요
질문하신분이 '클라이언트가 10분동안 packet 전송이 없는경우 자동으로 그 세션을 끊고싶다' 이런식의 질문인것 같은데요
만약 이런 경우엔 select 의 timeout 하고는 상관이 없습니다.
질문이 잘 이해가 되지 않네요^^

lapex의 이미지

Quote:

제가 원하는건 일정 시간동안 아무일도 일어나지 않을때 연결을 끊는것을
원하는데요....

이런 기능을 제공하는 함수가 linux 에 있는지 여부는 알지 못합니다.
그러나, 제가 이런류의 로직을 코딩할 때는 아래와 같이 했었습니다.

정해진 시간마다 server 에서 client 에 dummy packet 을 보냅니다.
client 에서 이 메시지에 대한 응답을 하지 않으면
그 때 그 socket 을 close 해 버립니다.

pynoos의 이미지

만일 서버에 접속하고 그 접속을 통해 뜸하게 data가 오고 간다면,

KEEPALIVE option을 사용하면 됩니다..

물론 그 일정 시간이라는 것을 마음대로 조절할 수는 없지만...

TCP packet으로 connection이 살아 있는지를 확인하고,

그렇지 않을 경우 끊어졌다는 신호가 tcp쪽에서 application으로

올라옵니다..

일정시간이 두 시간정도였던것 같은데... -.-

그리고, KEEPALIVE는 protocol stack 구현상 optional 이지만, 요즈음의 대부분은 구현되고 있는 것으로 알고 있습니다.

connection이 된 socket s에 대하여 다음과 같이 하면 됩니다.

int val = 1;
setsockopt( s, SOL_SOCKET, SO_KEEPALIVE, (char *) & val, sizeof( val ) );

Dr_stein의 이미지

음.. 제가 질문 드린건 frowt님 표현이 정확합니다. 그게 유닉스상에서는
select의 timeout이 그거(원하는 시간동안 packet이 오지 않을경우 자동으로 연결을 끊는거)인것 같은데 리눅스는 아닌거 같아서
질문을 드린거고요...제가 말하고 보니 정확한게 하나도 없네요 -_-;;죄송

그러면 리눅스에서 select함수의 timeout은 어떤의미인지 설명좀 부탁 드립니다. (__+);

앞마당 먹고 시작한 저그의 8할은 뮤탈 테크를 먼저 탄다. 하지만 나머지 2할때문에 항상 스켄이 모자란다. - _-;

pynoos의 이미지

linux 뿐아니라 모든 곳에서 select안에 들어가는 time out은

select 되기 시작한 순간부터 descriptor들의 심경에 변화가 생기지 않고 (recv,send,close,reset 등이 일어나지 않고..)

유지되는 시간을 말합니다.

소타의 이미지

리눅스에서는 timeval을 어디서 설정하느냐에 따라 select의 동작이 달라집니다.

tv.tv_sec = tv_sec;
tv.tv_usec = tv_usec;
while (1)
{
    select(fd_max,fd_set,NULL,NULL,tv);
}

while (1)
{
    tv.tv_sec = tv_sec;
    tv.tv_usec = tv_usec;
    select(fd_max,fd_set,NULL,NULL,tv);
}

두가지는 동작이 다릅니다.
후자가 타OS처럼 정상적으로 동작합니다.
전자 역시 처음엔 정상적으로 동작하지만 한바퀴 돌고나면 언제 tv 가 리셋되어 버리는지 무한 루프 돌듯이 돌아 버립니다.

진실은 어디 있는지 ( -_);;

송지석의 이미지

nonun wrote:
리눅스에서는 timeval을 어디서 설정하느냐에 따라 select의 동작이 달라집니다.

tv.tv_sec = tv_sec;
tv.tv_usec = tv_usec;
while (1)
{
    select(fd_max,fd_set,NULL,NULL,tv);
}

while (1)
{
    tv.tv_sec = tv_sec;
    tv.tv_usec = tv_usec;
    select(fd_max,fd_set,NULL,NULL,tv);
}

두가지는 동작이 다릅니다.
후자가 타OS처럼 정상적으로 동작합니다.
전자 역시 처음엔 정상적으로 동작하지만 한바퀴 돌고나면 언제 tv 가 리셋되어 버리는지 무한 루프 돌듯이 돌아 버립니다.

진실은 어디 있는지 ( -_);;


리눅스가 표준에 충실해서 그렇다고 문서에 나와있더군요.
그게 posix표준이었나 기억이 가물..
어쨌건 표준에는 select가 리턴되면 tv 안의 내용은 타임아웃까지 남은 시간이 됩니다.
그러니까 5초 타임아웃 걸어놓고 1초후에 select에서 나오면 tv는 4초가 되고요
tv에 다시 5초를 넣어주지 않고 그다음 다시 루프돌아서 select에서 기다리다 2초 후에 나오면 tv는 2초가 되는 거지요.
그러다 나중에 tv가 0초가 되면 그후로는 select에서 바로 빠져나와버립니다. 타임아웃이 0초니까 바로 타임아웃이 걸리는 것입죠.
호환성 있게 짜실려면 후자로 짜는 습관을 들이셔야 합니다. (사실 저도 윈도에서 돌던 소스를 리눅이로 바로 옮겼다가 저런 낭패를.. -- )
송지석의 이미지

예를 들어서 pseudo코드를 짜보겠습니다.

FD_SET(socket, &fd_set);
while(not_end) {
	tv.tv_sec = 10; 
	tv.tv_usec = 0; // 10초 타임아웃.
	result = select(fd_max,fd_set,NULL,NULL,tv); // fd_set의 recv에 관심있음.
	if (result == 0) // time out.
	{
		printf("no data for 10 sec....\n");
		not_end = FALSE;
	}
	if (result <0) // error?
	{
		perror("select");
		break;
	}	
	recv(...);
	/*데이터 받아서 할일 하기*/
}//while

printf("closing connection\n");
close(socket);
pynoos의 이미지

송지석 wrote:
예를 들어서 pseudo코드를 짜보겠습니다.

FD_SET(socket, &fd_set);
while(not_end) {
	tv.tv_sec = 10; 
	tv.tv_usec = 0; // 10초 타임아웃.
	result = select(fd_max,fd_set,NULL,NULL,tv); // fd_set의 recv에 관심있음.
	if (result == 0) // time out.
	{
		printf("no data for 10 sec....\n");
		not_end = FALSE;
	}
	if (result <0) // error?
	{
		perror("select");
		break;
	}	
	recv(...);
	/*데이터 받아서 할일 하기*/
}//while

printf("closing connection\n");
close(socket);

if (result == 0) // time out.
{
printf("no data for 10 sec....\n");
not_end = FALSE;
}

요안에 break 라도 넣어줘야.... 아래 recv 에서 block 안되지요..

송지석의 이미지

아 글쿤욥 ㄳㄳ

아 그러고 보니 select에서 에러가 나서 리턴값이 음수면 소켓을 닫다가 세그먼트폴트가 나는 경우도 있던 것 같습니다만... 잘 기억이.. (이놈의 머리가.. 치맨가 ㅠㅠ)
음수로 나오면 어쩌면 그냥 프로세스를 끝내는 게 나을지도 모르겠습니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.