프로그래밍 공부중인데. 의문점이 있어서 글을 올립니다.
글쓴이: 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
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; }위의 코드를 다음과 같이 고쳐보세요.
if (0 == ret) { // this is a 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; } else { printf("this is parent process\n"); }(0 == ret)은 부모 프로세스가 아니라 자식프로세스입니다.
본문을 잘못 복사&붙여넣기 했네요. 다시
본문을 잘못 복사&붙여넣기 했네요.
다시 말하자면,
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; }위의 코드를 다음과 같이 고쳐보세요.
if (0 == ret) { // this is a 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; } else { printf("this is parent process\n"); }to shint,
도와주고 싶어하는 마음은 알겠으나, 질문을 이해하기 위해 5~10분정도의 시간도 투자하기 아깝다면
답변을 안주는게 낫습니다. 가볍게 아님말고 식의 답변보다, 진지한답변이 질문자에게 도움이 됩니다.
감사합니다. 제가 제대로 이해하지 못하고 사용하고 있었네요.
덕분에 돌아가지 않고 시간을 아꼈습니다. 감사합니다. ^^
댓글 달기