min's devlog

UDP 에코 서버 본문

Linux/TCP IP Socket Programming

UDP 에코 서버

값진 2021. 4. 10. 22:33

파이프를 통해 에코메시지를 전달하는 UDP에코서버

  - 부모 프로세스는 write만 하고 자식 프로세스는 read만 하는 코드이다.

파일명 : udpserv_pipeecho.c

컴파일 : gcc -o udpserv_pipeecho udpserv_pipeecho.c
실행 : udpserv_pipeecho 9999

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<netinet/in.h>
#include<sys/time.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<errno.h>
#define MAX_BUFSZ 512
//파이프에 쓰는 데이터구조
typedef struct mesg{
        struct sockaddr_in addr; //클라이언트 주소
        char data[MAX_BUFSZ]; //에코할 데이터
}mesg_t
void child_start(int sock, int pipefd[]); //자식 프로세스
void parent_start(int sock, int pipefd[]); //부모 프로세스
void errquit(char *mesg) {perror(mesg); exit(1);}
int main(int argc, char **argv){
        struct sockaddr_in servaddr;
        pid_t pid;
        int sock,
                pipefd[2],

                port,
                len=sizeof(struct sockaddr);
        if(argc!=2){
                printf("\n Usage : %sport\n",argv[0]);
                exit(EXIT_FAILURE);
        }

포트번호

        port=atoi(argv[1]);
        sock=socket(AF_INET,SOCK_DGRAM,0);
        if(sock<0){
                perror("socket failed");
                exit(EXIT_FAILURE);
        }
        bzero(&servaddr,len);
        servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
        servaddr.sin_family=AF_INET;
        servaddr.sin_port=ntohs(port);
        bind(sock,(struct sockaddr*)&servaddr,len);

파이프 생성

        if(pipe(pipefd)==-1)
                errquit("pipe fail");
        pid=fork();
        if(pid<0) errquit("fork fail");
        else if(pid>0) parent_start(sock,pipefd);
        else if(pid==0) child_start(sock,pipefd);
        return 0;
}

 

자식 프로세스

void child_start(int sock, int pipefd[]){
        mesg_t pmsg;
        int nbytes=0;
        len = sizeof(struct sockaddr);
        close(pipefd[1]);

        while(1){
        //파이프로부터 읽기
                nbytes=read(pipefd[0],(char *)&pmsg, sizeof(mesg_t));

                if(nbytes<0)
                        errquit("read failed");
                printf("Child : read from pipe\n",nbytes);
                //파이프로부터 읽은 데이터를 에코

                nbytes = sendto(sock,
                                       &pmsg.data,
                                       strlen(pmsg.data),
                                        0,
                                        (struct sockaddr*)&pmsg.addr, len);
                printf("Child : %d bytes echo response\n",nbytes);
                printf("-------------------------\n");
        } //while
}

 

부모 프로세스

void parent_start(int sock, int pipefd[]) {
        mesg_t pmsg;
        int nbytes;
                len=sizeof(struct sockaddr);

        //읽기 파이프 닫음
        close(pipefd[0]);

        printf("my echo server wait...\n");
        while(1){

                //소켓으로부터 읽기
                nbytes=recvfrom(sock,
                                        (void*)&pmsg.data,
                                        MAX_BUFSZ,
                                         0,
                                         (struct sockaddr*)&pmsg.addr,&len);
                if(nbytes<0)

                        errquit("recvfrom failed ");
                printf("Parent : %d bytes recv from socket\n",nbytes);

                pmsg.data[nbytes]=0;

                //소켓으로부터 읽은 데이터를 파이프에 쓰기
                        if(write(pipefd[1], (char*)&pmsg, sizeof(pmsg))<0)
                                perror("write fail");
                printf("Parent:write to pipe\n",nbytes);
        }//while
}

 

'Linux > TCP IP Socket Programming' 카테고리의 다른 글

메시지 수신 프로세스  (0) 2021.04.10
파이프 기반의 프로세스간 통신  (0) 2021.04.10
SIGCHLD, wait()  (0) 2021.04.09
alarm() 인터럽트  (0) 2021.04.09
System Call 수행 중 함수 처리  (0) 2021.04.09
Comments