검색결과 리스트
글
블락이 걸리는 함수에 대해서만 non-block을 해줬다가 다시 걸고,
멀티플렉스로 연결을 받아 접속을 처리하고 있습니다.
select가 파일디스크립터를 모두 검사하는 것이 마음에 들지 않아서
검사할 파일디스크립터를 리스트로 구현하려고 했지만,
귀찮은 마음에 그냥 돌립니다... 몇 개 안 될테니까요 ㅡㅡㅋ
앞으로 이것을 한 쓰레드로 하고,
DB에 저장하는 쓰레드로 전달하는 것을 구현해야겠네요.
serv_sock = socket(PF_INET, SOCK_STREAM, 0); if(serv_sock == -1) error_handling("socket() error!"); memset((void*)&serv_addr, 0x00, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htons(INADDR_ANY); serv_addr.sin_port = htons(atoi(argv[1])); if( bind(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1) error_handling("bind() error!"); // listen() non-block if( block_switch(serv_sock, OFF) == -1) error_handling("fcntl error!()"); #ifdef __DEBUG__ printf("block_switch mode\n"); #endif if( listen(serv_sock, 5) == -1) error_handling("listen() error!"); #ifdef __DEBUG__ printf("listeing... \n"); #endif // listen() block if( block_switch(serv_sock, ON) == -1) error_handling("fcntl error!()"); #ifdef __DEBUG__ printf("block mode\n"); #endif #ifdef __DEBUG__ printf("listen() success!! sock number: %d\n", serv_sock); #endif FD_ZERO(&readfds); FD_SET(serv_sock, &readfds); fd_max = serv_sock; for( ;; ) // 무한루프 { int fd, str_len; int clnt_sock, clnt_len; struct sockaddr_in clnt_addr; int tempflag; tempfds = readfds; result = select( fd_max+1, &tempfds, NULL, NULL, NULL ); if(result < 0 && errno == EINTR) continue; #ifdef __DEBUG__ printf("Now select() running...\n"); #endif #ifdef __DEBUG__ fputc('x', stderr); #endif for( fd = 0; fd < fd_max+1; fd++ ) { if(FD_ISSET(fd, &tempfds)) { if(fd == serv_sock) // 서버소켓에 왔으면 접속요청 { clnt_len = sizeof(clnt_addr); // accept() non-block if( block_switch(serv_sock, OFF) == -1) error_handling("fcntl error!()"); clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_addr, &clnt_len); if(clnt_sock < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) { fprintf(stderr, "accept() Failed!\n"); continue; } // accept() block if( block_switch(serv_sock, ON) == -1) error_handling("fcntl error!()"); FD_SET(clnt_sock, &readfds); if(clnt_sock > fd_max) fd_max = clnt_sock; #ifdef __DEBUG__ printf("client connect : fd %d\n", clnt_sock); #endif } else // fd == serv_sock이 아니면 clnt_sock으로 오는 요청 { memset((void*)BUF, 0x00, BUFSIZE); // recv() non-block if( block_switch(serv_sock, OFF) == -1) error_handling("fcntl error!()"); str_len = recv(clnt_sock, BUF, BUFSIZE, 0); if(str_len < 0 && ( errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) ) { fprintf(stderr, "accept() Failed!\n"); continue; } // recv() block if( block_switch(serv_sock, ON) == -1) error_handling("fcntl error!()"); if( str_len == 0 ) // 0면 연결종료 요청 { FD_CLR(fd, &readfds); close(fd); printf("Connect close : fd %d\n", fd); } else // 데이터를 보내왔을 때.. { printf("\nThis is BUF-----------------\n"); printf("%s\n", BUF); printf("------------------------------\n\n"); } } // clnt_sock으로 어떠한 요청이 왔을 때의 처리들 끝 } // IS_FDSET 끝 } // fd 한 바퀴 돌면서 어떠한 요청이 있었는지 검사의 끝 /////////////////////////////////////////////////////////////// } // for( ;; ) end close(serv_sock); // serv_sock 종료. 이 때도 error 처리가 필요함 return 0; } void error_handling(char *message) { fputs(message, stderr); fputc('\n', stderr); exit(1); } int block_switch(int fd, int block_switch) { int flags; flags = fcntl( fd, F_GETFL, 0); if( block_switch == OFF ) return fcntl( fd, F_SETFL, flags | O_NONBLOCK); else return fcntl( fd, F_SETFL, flags & (~O_NONBLOCK)); }
'Network > socket(c&c++)' 카테고리의 다른 글
클라이언트 소켓에서 Connection Time out (0) | 2012.10.19 |
---|---|
socket connect 함수의 처리시간의 조정 방법 (0) | 2012.10.19 |
The C10K problem (0) | 2012.10.19 |
TCP 기반의 소켓 통신 101 (0) | 2012.10.19 |
넌블럭킹 소켓 (0) | 2012.10.19 |
RECENT COMMENT