소켓 프로그램에서 사용하는 select 함수의 timeval 매개변수에 대한 궁금증입니다
네트워크 소켓 프로그램에 처음으로 입문해서 이것저것 모르는게 많습니다..
대충 서버와 클라이언트간 통신 프로그램은 짜서 구동시켰는데 tcp/ip 소켓 통신 프로그램을 짜다보니
통신보다 중요한 것이 에러처리 더군요..
지식이 얇아 한계에 부딪혔습니다.
2주째 에러 처리에 대해서 보고 있는데.. 현재 문제는 서버단이 아닌 클라이언트 단입니다 .
connect ,read, send 등의 system call들의 blocking 문제 (소켓이 맨처음 생성될 때 blocking mode로
된다는것두 얼마전에 겨우 알았습니다... =.=)
를 해결하기 위해서 이것저것 찾던 중
1. select 함수의 timeval 매개 변수 이용
2. alarm-signal 함수 이용
두가지 방법을 알게 되었습니다.
이중 select 함수에 대한 것인데요..
구성은
1. 서버로 리퀘스트 보냄
2. select 함수에서 timeval 설정하고 대기
3. select 리턴 값에 따라 처리
이런식입니다. 일단 서버에서 리퀘스트에 대한 서비스를 해주면 timeval과 상관없이 잘 됩니다.
문제는 제가 고의로 서버의 service 루틴을 막고(즉 write를 하지 않고) select 에서 기다리면
설정해준 timeval이 지나면 timeout이 호출 되어야 하는데 select 자체가 block이 되어 버립니다.
몇가지 테스트를 해봤는데..
1.서버로 리퀘스트를 하지 않고 select 함수를 사용하면 timeout이 잘 됩니다.
2. readfds 값을 null로 바꾸고 select함수를 사용하면 timeout이 잘 됩니다.
원하는 것은 서버로 리퀘스트 날린 후에 select가 block 되지 않고 timeout이 되는 것입니다..ㅠ.ㅠ
고수님들의 애정어린 관심 부탁드릴께요.. 현재 테스트 중인 소스 코드 입니다..
================ select 함수 사용하는 소스 코드=======================
bzero((char *)read_data, MAX_BUFF);
bzero((char *)write_data, MAX_BUFF);
bzero((char *)&timeout, sizeof(timeout));
// timeout 30 sec
timeout.tv_sec = 10;
timeout.tv_usec = 0;
// sConnect = socket_connect();
strcat(write_data, "PT");
strcat(write_data,"PE");
write_data[strlen(write_data)]=0;
nfds = sockfd + 1;
send(sockfd, write_data, strlen(write_data), 0);
for(;;)
{
timeout.tv_sec = 10;
timeout.tv_usec = 0;
FD_ZERO(&read_fds);
FD_ZERO(&write_fds);
FD_ZERO(&except_fds);
// for(i = 0; i < nfds; i++)
FD_SET(sockfd, &read_fds);
FD_SET(sockfd, &write_fds);
FD_SET(sockfd, &except_fds);
FD_CLR(sockfd, &write_fds);
// FD_CLR(sockfd, &read_fds);
temp_fds = read_fds;
ret = select(nfds,&temp_fds, /*&write_fds*/NULL, /*&except_fds*/NULL, &timeout);
switch(ret)
{
case -1:
perror("select error\n");
exit(0);
break;
case 0:
perror("select timeout\n");
exit(0);
break;
default:
// for (i=0; i< nfds; i++)
// {
if(FD_ISSET(sockfd, &temp_fds))
{
while((read(sockfd, read_data,MAX_BUFF)) > 0)
{
read_data[strlen(read_data)] = 0;
printf("(%d)[%d]%s\n",ret, sockfd, read_data);
break;
}
}
else if(FD_ISSET(sockfd, &write_fds))
{
while((write(sockfd, write_data,MAX_BUFF)) > 0)
{
// write_data[strlen(write_data)] = 0;
printf("(%d)[%d]%s\n",ret, sockfd, write_data);
break;
}
}
else
printf("(%d)[%d]:%d\n",ret, sockfd, errno);
break;
// }
}
bzero((char *)read_data, MAX_BUFF);
usleep(1000);
}
===========================끝================================
댓글 달기