[완료]select 사용 질문입니다.
많은 답변과 도움 감사합니다. 덕분에 문제를 해결했습니다.
=========================
안녕하세요
소켓통신으로 클라이언트를 만들고 있습니다. 업무 지시에 따라 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부분을 책에서 보고 테스트용 에코서버에 적용을 해봤지만 제예상과는 다른 동작을 하고 있습니다.
어제 글을 올렸는데 아침에 출근해보니 안올라가서 다시 씁니다 ㅠㅠ
도움에 손길이 절실합니다.
select를 write 스트림에
select를 write 스트림에 할 경우 의미가 'write 준비가 된경우 성공 리턴'입니다.
처음 select 문에서 write 만 검사하는 데 저 호출은 대부분의 거의 성공 리턴합니다.
타임아웃이 발생할려면 write 버퍼가 꽉 차서 write 가 안될 때 입니다.
---------
간디가 말한 우리를 파괴시키는 7가지 요소
첫째, 노동 없는 부(富)/둘째, 양심 없는 쾌락
셋째, 인격 없는 지! 식/넷째, 윤리 없는 비지니스
이익추구를 위해서라면..
다섯째, 인성(人性)없는 과학
여섯째, 희생 없는 종교/일곱째, 신념 없는 정치
---------
간디가 말한 우리를 파괴시키는 7가지 요소
첫째, 노동 없는 부(富)/둘째, 양심 없는 쾌락
셋째, 인격 없는 지! 식/넷째, 윤리 없는 비지니스
이익추구를 위해서라면..
다섯째, 인성(人性)없는 과학
여섯째, 희생 없는 종교/일곱째, 신념 없는 정치
네
저도 그렇게 이해가 되는데요...
그렇다면 윈도우 환경에서 Write를 대기 하고 있을때 timeout을 발생을 시키려면 도대체 어떻게 해야할까요
윈도나 리눅스나 같은 결과 아닐까요?
개념상으로 소켓이 연결된 정상 상태라면 write가 timeout 발생할 일은 거의 없죠.
아예 전송 불가 또는 전송 중 에러가 나겠지만...
윗분 말대로 버퍼가 꽉 차지 않은 이상은...
머...답이 될진 모르지만 가정한 사실을 정상적인 상황으로 규약을 정하는 방법 밖에는
없는 듯 합니다. 서버와 클라이언트가 약속을 해야겠죠.
소켓이 연결되면 누가 먼저 메시지를 보내고 누가 받고...
또다른 방법은 약간은 오해의 소지가 있을 수 있으나 메시지를 보내는 시점의 타임 아웃에 대한
요구를 소켓 커넥션과 같이 보는 거죠. 클라이언트라면 계속 연결시도를 하게 될테고(정상적인
경우라면...) 이렇게 연결 시도 중에는 write를 할 수 없겠죠. 이에 대한 타임 아웃을 전송
타임 아웃으로 볼 수도 있다는 말입니다. ;;;
-------------
포탈이는 불사신
-------------
포탈이는 불사신
댓글 달기