프로그래밍 공부중인데. 의문점이 있어서 글을 올립니다.
글쓴이: LWC3 / 작성시간: 일, 2015/10/11 - 11:56오후
아래 등록한 코드로 소켓 프로그래밍을 공부하고 있는데 궁금한 점이 있어서 글을 올립니다.
아래 서버 프로그램을 실행 시킨 후에 Ctrl+c 를 사용해서 SIGINT 시그널을 발생시키면
init_handler 가 잘 동작합니다. 그런데 telnet 으로 한번 연결 후에는 시그널을 발생 시켜도
init_handler 가 동작하지 않습니다. 왜 accept 이후에는 시그널이 동작하지 않는지요?
그리고 하나더 궁금한 점은 accept 이후에 root@ubuntu:~/work/c/server$ 이 출력되는데요.
부모 프로세스가 종료되어야 커맨드 입력 부분이 출력되는 부분이지 않나요?
알려주시면 감사하겠습니다. ㅎ..;
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<errno.h> #include<string.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #include<arpa/inet.h> #include<sys/wait.h> #include<signal.h> #define MYPORT 3490 // the port users will be connecting to #define BACKLOG 10 // how many pending connections queue will hold void sigchld_handler(int s) { while(wait(NULL) > 0); } void init_handler(int s) { printf("\t init start\n"); } int main(argc, argv) int argc; char** argv; { int sockfd, new_fd; // listen on sock_fd, new connection on new_fd struct sockaddr_in my_addr; // my address information struct sockaddr_in their_addr; // connector's address information int sin_size; struct sigaction sa, sig_init; int yes=1; int ret; if((sockfd=socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); return 1; } if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { perror("setsockopt_reuseaddr"); return 1; } my_addr.sin_family = AF_INET; // host byte order my_addr.sin_port = htons(MYPORT); // short, network byte order my_addr.sin_addr.s_addr = htonl(INADDR_ANY); // automatically fill with my IP // my_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // manual IP bzero(&(my_addr.sin_zero), 8); // zero the rest of the struct if(bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) { perror("bind"); return 1; } if(listen(sockfd, BACKLOG) == -1) { perror("listen"); return 1; } sa.sa_handler = sigchld_handler; // reap all dead processes sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; if(sigaction(SIGCHLD, &sa, NULL) == -1) { perror("sigaction"); return 1; } sig_init.sa_handler = init_handler; sigemptyset(&sig_init.sa_mask); if(sigaction(SIGINT, &sig_init, NULL) == -1) { perror("sigaction_init"); return 1; } while(1) { // main accept() loop sin_size = sizeof(struct sockaddr_in); if((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1) { perror("accept"); continue; } printf("server: got connection from %s\n", inet_ntoa(their_addr.sin_addr)); ret = fork(); if(0==ret) { // this is parent process printf("this is parent process\n"); }else{ // this is child process printf("this is child process\n"); close(sockfd); // child doesn't need the listener if(send(new_fd, "Hello, world!\n", 14, 0) == -1) perror("send"); close(new_fd); printf("child process exit\n"); return 1; } printf("\t process : %d, parent process : %d, try to close\n", getpid(), getppid()); close(new_fd); // parent doesn't need this } return 0; }
Forums:
저라면...
- Ctrl + 모든 키를 입력해보세요. ㅇ_ㅇ;; Ctrl + Z, Ctrl + \ 등등...
- Unix System Programming for SVR4 책에 자세히 나와있습니다. 책보고 따라해보시면 편합니다.
- 터미널 명령어도 몇개 되네요. ㅇ_ㅇ;;
- 모든 변수와 함수를 검색해보겠습니다.
- 각 함수에 인자값. 리턴값. 오류값을 확인해보겠습니다.
- select() 도 있습니다.
----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.
매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.
각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com
if(0!=ret) { // this is
위의 코드를 다음과 같이 고쳐보세요.
(0 == ret)은 부모 프로세스가 아니라 자식프로세스입니다.
본문을 잘못 복사&붙여넣기 했네요. 다시
본문을 잘못 복사&붙여넣기 했네요.
다시 말하자면,
위의 코드를 다음과 같이 고쳐보세요.
to shint,
도와주고 싶어하는 마음은 알겠으나, 질문을 이해하기 위해 5~10분정도의 시간도 투자하기 아깝다면
답변을 안주는게 낫습니다. 가볍게 아님말고 식의 답변보다, 진지한답변이 질문자에게 도움이 됩니다.
감사합니다. 제가 제대로 이해하지 못하고 사용하고 있었네요.
덕분에 돌아가지 않고 시간을 아꼈습니다. 감사합니다. ^^
댓글 달기