네트워크 프로그래밍 중 파일 디스크립터 관련 질문입니다.
안녕하세요. 공부하면서 이 사이트에서 많은 도움을 받고있습니다.
다름이 아니라 네트워크 프로그래밍 공부하며 멀티 프로세스로 채팅프로그램을 작성해보는 중 막히는 부분이 있어 이렇게 질문을 올리게 되었습니다.
최종적인 질문은 이렇습니다.
"부모 프로세스에 새로 생기는 파일 디스크립터 정보를 자식 프로세스들에게 공유하거나 전달하여 부모 프로세스와 같은 파일 디스크립터 정보를 가질 수 있는 방법이 있나요?" 입니다.
아래 소스코드는 서버 소스코드입니다.
전체적인 흐름은 listen() 까지는 일반적인 예제에서 그대로 사용하였습니다. 그 다음부터는 while문을 통해 부모 프로세스는 반복을합니다.
연결 요청이 들어 오게되면 fork() 호출을 통해 자식 프로세스를 생성하고, 자식 프로세스는 연결된 클라이언트로 부터 메세지를 받습니다, (여기 까진 성공적입니다.)
근데 자식 프로세스는 클라이언트로 부터받은 메세지를 파일 디스크립터를 통해 다른 자식 프로세스들이 연결된 클라이언트에게 메세지를 전달해야합니다.
클라이언트를 3개를 연결하여 메세지 송수신 테스트를하면서 알게된 부분은 파일 디스크립터 정보가 각각의 프로세스마다 다르다는 점을 알게되었습니다.
즉, 부모 프로세스는 연결요청에 의해 생성된 파일 디스크립터 정보가 계속 쌓이고 마지막으로 fork하여 생성된 자식 프로세스3은
앞에 생성된 자식 프로세스1, 2에게 메세지를 전송 할 수 있지만 나머지 자식 프로세스는 자기 자신이 생성된 후의 파일 디스크립터 정보를 가지고 있지 않기 때문에
제가 원하는 데로 다른 자식 프로세스에게 연결된 클라이언트로 메세지를 전송할 수 없다는걸 확인하였습니다.
결국, 마지막에 생성된 자식 프로세스는 크게 상관없지만 앞에 생성된 자식 프로세스들에게는 추가로 적인 파일디스크립터 정보를 넘겨줘야 하는데....
부모, 자식 프로세스간 파일 디스크립터 정보를 똑같이 하거나 새로 생성된 정보를 넘겨줄 방법을 찾고싶습니다.!!
#include <stdio.h> #include <sys/socket.h> #include <arpa/inet.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #define MAX_BUF 1024 //TCP/IP Server int main(int argc, char *argv[]) { int serv_sock, clnt_sock, pid, i; int arr[10] = {0,}; int clnt_count = 0; char message[MAX_BUF]; struct sockaddr_in serv_addr; struct sockaddr_in clnt_addr; socklen_t clnt_addr_size; if(argc != 2) { printf("input : %s <prot number>\n",argv[0]); serv_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if(serv_sock == -1) printf("socket() error\n"); memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(atoi(argv[1])); if(bind(serv_sock, (struct sockaddr*) &serv_addr, sizeof(serv_addr))== -1) printf("bind() error\n"); if(listen(serv_sock, 5) == -1 ) printf("listen() error\n"); clnt_addr_size = sizeof(clnt_addr); printf("%d\n",serv_sock); while(1) { clnt_sock = accept(serv_sock, (struct sockaddr*) &clnt_addr, &clnt_addr_size); if(clnt_sock == -1) { continue; } else { arr[clnt_count] = clnt_sock; clnt_count+=1; } memset(message, 0, sizeof(message)); pid = fork(); get_pid = getpid(); if(pid < 0) { printf("fork Error\n"); } else if(pid == 0) { //자식 printf("fd : %d, pid : %d\n",clnt_sock,get_pid); close(serv_sock); while(1) { if(read(clnt_sock, message, sizeof(message))==-1) continue; if(strcmp(message,"q\n") == 0) { printf("%d(%d) END\n",get_pid, clnt_sock); close(clnt_sock); exit(0); } else { for(i=0; i<clnt_count; i++) { if(arr[i] != 0) write(arr[i], message, sizeof(message)); } memset(message, 0, sizeof(message)); } } } else { //부모 } } close(serv_sock); return 0; }
fork방식이라 IPC들 중 하나를 써야 할 것
fork방식이라 IPC들 중 하나를 써야 할 것 같은데요.
학습 목적이시면, 일단 이번 주제를 스킵하고, IPC 방법들을 공부한 후에 다시 구상해 보시는게 어떨까 합니다.
Signature :) - "여유를 갖고 행동하되 게을러지지 말자"
댓글 달기