>

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<signal.h>
#include<sys/wait.h>
#include<errno.h>
void sigHandler(int sig)
{
	int pid;
	int status;
	pid = wait(&status);
	printf("pid[%d] terminated\n",pid);
}
int process_init()
{
	int state;
	struct sigaction act;
	act.sa_handler = sigHandler;
	sigemptyset(&act.sa_mask);
	act.sa_flags=0;
	
	state = sigaction(SIGCHLD,&act,0);
	if(state !=0)
	{
		printf("signal error\n");
		exit(1);
	}
}
int sock_init(int port)
{
	struct sockaddr_in server_addr;
	int server_fd;
	int len;
	if((server_fd = socket(AF_INET, SOCK_STREAM,0))==-1)
	{
		printf("socket error\n");
		exit(0);
	}
	memset(&server_addr, 0x00, sizeof(server_addr));
	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	server_addr.sin_port = htons(port);
	if(bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr))<0)
	{
		printf("bind error\n");
		exit(0);
	}
	if(listen(server_fd,5)<0)
	{
		printf("listen error\n");
		exit(0);
	}
	return server_fd;
}
int do_write(int fd,char *buf)
{
	return write(fd,buf,strlen(buf));
}
int do_read(int fd, char *buf)
{
	return read(fd,buf,sizeof(buf));
}
int service(int fd)
{
	char buf[120];
	do_write(fd,"Hello Sir?\n");
	do_read(fd,buf);
	exit(1);
}
int main(int argc, char *argv[])
{
	int server_fd,client_fd;
	pid_t pid;
	int len;
	struct sockaddr_in client_addr;
	if(argc !=2)
	{
		printf("usage : %s [port]\n",argv[0]);
		return 0;
	}
	process_init();
	server_fd = sock_init(atoi(argv[1]));
	while(1)
	{
		len = sizeof(client_addr);
		if((client_fd = accept(server_fd ,(struct sockaddr *)&client_addr, &len))<0)
		{
			if(errno == EINTR)
				continue;
			else
				printf("accept error\n");
		}
		if((pid = fork())<0)
		{
			printf("fork error\n");
			exit(0);
		}
		else if(pid > 0)
		{
			close(client_fd);
			continue;
		}
		else if(pid == 0)
		{
			close(server_fd);
			service(client_fd);
		}
	}
}



sock_init 함수는 socket, bind, listen 함수로 서버 설정을 하는 함수이다.

fork를 통해 자식프로세스를 생성한다 => 부모면 그대로 서버소켓 유지, 자식이면 서비스 실행. 

SIGCHLD 시그널을 처리하기 위해 sigaction 함수를 쓴다.

wait 함수는 자식프로세스의 종료 상태를 가져올 때까지 부모를 기다리게 할 수 있다.

accept문을 그냥 쓰면 무한반복되는데 이를 방지하기 위해 errno가 EINTR 일 때에도 처리해준다.

Posted by Mungsul
,