select함수를 이용한 에코서버에서 궁금한게있습니다.
글쓴이: korisaram / 작성시간: 일, 2003/07/13 - 10:50오전
1: int main(int argc, char **argv) 2: { 3: int serv_sock; 4: struct sockaddr_in serv_addr; 5: 6: fd_set reads, temps; 7: int fd_max; 8: 9: char message[BUFSIZE]; 10: int str_len; 11: struct timeval timeout; 12: 13: if(argc!=2){ 14: printf("Usage : %s <port>\n", argv[0]); 15: exit(1); 16: } 17: 18: serv_sock = socket(PF_INET, SOCK_STREAM, 0); 19: serv_addr.sin_family = AF_INET; 20: serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); 21: serv_addr.sin_port = htons(atoi(argv[1])); 22: 23: if(bind(serv_sock, (struct sockaddr *) &serv_addr, sizeof (serv_addr))) 24: error_handling("bind() error"); 25: if(listen(serv_sock, 5)==-1) 26: error_handling("listen() error"); 27: FD_ZERO(&reads); 28: FD_SET(serv_sock, &reads); 29: fd_max=serv_sock; 30: 31: while(1) 32: { 33: int fd, str_len; 34: int clnt_sock, clnt_len; 35: struct sockaddr_in clnt_addr; 36: 37: temps=reads; 38: timeout.tv_sec = 5; 39: timeout.tv_usec = 0; 40: 41: if(select(fd_max+1, &temps, 0, 0, &timeout)==-1) 42: error_handling("select() error"); 43: 44: for(fd=0; fd<fd_max+1; fd++) 45: { 46: if(FD_ISSET(fd, &temps)) 47: { 48: if(fd==serv_sock) { /* 연결 요청인 경우 */ 49: clnt_len = sizeof(clnt_addr); 50: clnt_sock = accept(serv_sock, (struct sockaddr *)&clnt_addr, &clnt_len); 51: FD_SET(clnt_sock, &reads); 52: if(fd_max<clnt_sock) 53: fd_max=clnt_sock; 54: printf("클라이언트 연결 : 파일 디스크립터 %d \n", clnt_sock); 55: } 56: else { 57: str_len = read(fd, message, BUFSIZE); 58: if(str_len ==0){ /* 연결 종료 요청인 경우 */ 59: FD_CLR(fd, &reads); 60: close(fd); 61: printf("클라이언트 종료 : 파일 디스크립터 %d \n", fd); 62: } 63: else{ 64: write(fd, message, str_len); 65: } 66: } 67: } //if(FD_ISSET(fd, &temps)) 68: } //for(fd=0; fd<fd_max+1; fd++) 69: } //while(1) 70: }
위코드는 select문으로 만든 echo서버입니다. 제가 공부하는 책 예제인데
분석하다 보니 이해가 안가는 부분이있어서 질문들립니다.
44행에서 fd를 0부터 시작해서 서버소켓까지 for문으로 돌리고 있습니다.
fd가 0은 표준입력,1은 표준출력,2는 표준 에러라고 알고있습니다.
제생각으로는 fd를 3부터 for문으로 돌려서 클라이언트가 접속시도할때마다
어떤대응을 하게 만들어야할것 같은데 왜 0부터 for루프를 돌리는 지가
궁금합니다.
그리고 꼭 for문을 0부터 돌려야한다면 fd가 0일때 57행이 실행되어서
키보드로 값을 입력하면 그게 읽혀질건데 왜 서버에 저런게 필요한지도
궁금합니다.
Forums:
누군가 답글 달아주실거라 사료되어 그냥 있었는데이론~ 썰렁~굉
누군가 답글 달아주실거라 사료되어 그냥 있었는데
이론~ 썰렁~
굉장히 복잡한거 같으면서도 괜찮군요.....
좋은 기법인거 같네요. 단지 이것은 동시 1024(Linux에서)개 이상의 클라이언트를
받지 못하는 단점이 있어요......
일단 반드시 0,1,2 가 예약이 아닐수도 있다는 점.
누군가가 프로그램이 시작되고서 표준입/출력 을 전부 close한다면
그 만큼 핸들에 여유가 생기고 원하지 않는 입출력을 막을수 있겠죠?
main에서
int i;
for(i = 0;i < 3;i++)close(i);
이렇게 해보세요. 이게 어떻게 되버리는지.... 기가막히죠?
확인은 /proc/<pid>/fd 아시죠?
댓글 달기