[완료]select 사용 질문입니다.

anaud2의 이미지

많은 답변과 도움 감사합니다. 덕분에 문제를 해결했습니다.
=========================
안녕하세요

소켓통신으로 클라이언트를 만들고 있습니다. 업무 지시에 따라 timeout을 설정을 해야되는데요 최대
60초 사용자가 설정을 할수 있게 되어 있기에 timeout을 설정할수 있는 부분을 만들어야 합니다.적용부분은 전송 수신 connet 입니다.
여러가지 방법을 들었는데 그중에서 select를 사용하려고 하고 있구요. 일단은 전송과 수신에만 적용을 시켰습니다.

일단 소스를

int sock;
int result=0;
int fd_max;
fd_set reads, temps;
struct timeval timeout;

FD_ZERO(&reads);
FD_SET(sock, &reads);
fd_max = sock;
while(1)
{
temps=reads;
timeout.tv_sec = 5;
timeout.tv_usec = 0;

fgets(message, sizeof(message), stdin);//메세지 입력
if(!strcmp(message,"q\n")) break;

result = select(fd_max+1, 0, &temps, 0, &timeout);//전송을 검사&temps 두번째위치

if(result == -1) error_handling("select() error");//에러검사
else if (result == 0) error_handling("timeout");//timeout 검사

else {
if(FD_ISSET(sock, &temps)) {//select를 호출한게 sock인지 검사
str_len=write(sock, message, strlen(message)); /* 메시지 전송 */
}
}
timeout.tv_sec = 5;
timeout.tv_usec = 0;

result = select(fd_max+1, &temps, 0, 0, &timeout);//수신검사&temps 첫번째위치

if(result == -1) error_handling("select() error");//에러검사
else if (result == 0) error_handling("timeout");//timeout 검사
else {
if(FD_ISSET(sock, &temps)) {//select를 호출한게 sock인지 검사
recv_num=read(sock, &message[recv_len], str_len-recv_len);
}
}

message[str_len]=0;
printf("서버로부터 전송된 메시지 : %s \n", message);
}
간단하게 쓸데없는 부분을 제외하 select위주로 소스를 편집했습니다.
테스트를 2가를 했는데요 서버가 처음 read를 안하고 write를 할때 제생각에는 여기서 timeout이 발생해야한다고 생각했습니다. 그래야 제목적에 맞으니까요. 그러나 결과는 그냥 지혼자 전송-_-;;

두번째 테스트 read는 하지만 write를 안할때 이부분도 timeout을 기대했지만 바로 지혼자 전송 바로 recv끝나버림-_- 에러발생안함 타임아웃 발생안함 스무스 하게 메세지 입력단꼐로 옴

모든상황이 바로 스무스하게 지혼자 전송하고 바로 메세지 입력단계로 오네요 ㅠㅠ 제생각에는 저렇게 사용되는게 맞는거 같은데 왜 에러가 날까요 ㅠㅠ

select부분을 책에서 보고 테스트용 에코서버에 적용을 해봤지만 제예상과는 다른 동작을 하고 있습니다.
어제 글을 올렸는데 아침에 출근해보니 안올라가서 다시 씁니다 ㅠㅠ

도움에 손길이 절실합니다.

IsExist의 이미지

select를 write 스트림에 할 경우 의미가 'write 준비가 된경우 성공 리턴'입니다.
처음 select 문에서 write 만 검사하는 데 저 호출은 대부분의 거의 성공 리턴합니다.
타임아웃이 발생할려면 write 버퍼가 꽉 차서 write 가 안될 때 입니다.
---------
간디가 말한 우리를 파괴시키는 7가지 요소

첫째, 노동 없는 부(富)/둘째, 양심 없는 쾌락
셋째, 인격 없는 지! 식/넷째, 윤리 없는 비지니스

이익추구를 위해서라면..

다섯째, 인성(人性)없는 과학
여섯째, 희생 없는 종교/일곱째, 신념 없는 정치

---------
간디가 말한 우리를 파괴시키는 7가지 요소

첫째, 노동 없는 부(富)/둘째, 양심 없는 쾌락
셋째, 인격 없는 지! 식/넷째, 윤리 없는 비지니스

이익추구를 위해서라면..

다섯째, 인성(人性)없는 과학
여섯째, 희생 없는 종교/일곱째, 신념 없는 정치

anaud2의 이미지

저도 그렇게 이해가 되는데요...

그렇다면 윈도우 환경에서 Write를 대기 하고 있을때 timeout을 발생을 시키려면 도대체 어떻게 해야할까요

pizza1977의 이미지

개념상으로 소켓이 연결된 정상 상태라면 write가 timeout 발생할 일은 거의 없죠.
아예 전송 불가 또는 전송 중 에러가 나겠지만...
윗분 말대로 버퍼가 꽉 차지 않은 이상은...
머...답이 될진 모르지만 가정한 사실을 정상적인 상황으로 규약을 정하는 방법 밖에는
없는 듯 합니다. 서버와 클라이언트가 약속을 해야겠죠.
소켓이 연결되면 누가 먼저 메시지를 보내고 누가 받고...
또다른 방법은 약간은 오해의 소지가 있을 수 있으나 메시지를 보내는 시점의 타임 아웃에 대한
요구를 소켓 커넥션과 같이 보는 거죠. 클라이언트라면 계속 연결시도를 하게 될테고(정상적인
경우라면...) 이렇게 연결 시도 중에는 write를 할 수 없겠죠. 이에 대한 타임 아웃을 전송
타임 아웃으로 볼 수도 있다는 말입니다. ;;;

-------------
포탈이는 불사신

-------------
포탈이는 불사신

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.