리눅스에서 pipe를 통한 프로세스간 통신을 통해 클라이언트 - 서버 프로그램의 구조와 흐름을 애해해보자.
일단 코드에는 다음과 같은 모드를 추가했다.
Read 모드, Write 모드, Exit 모드를 추가한다.
read모드 : 사용자에게 파일명, 경로, 읽을 바이트 수를 입력 받고 화면에 출력한다.
write모드 : 사용자에게 파일명, 경로, 문자열을 입력 받고 파일에 출력하며 화면에는 그 바이트 수를 출력한다.
exit모드 : 프로그램을 종료한다.
수행 순서
텍스트 파일인 test.txt를 활용하여 수행하였고 read, write 모드 순으로 수행하였다.
1. read 모드에서는 byte단위로 캐릭터를 불러와서 화면에 출력하도록 하였다.
2. wirte 모드에서는 operatingsystem good을 입력하였고 그 결과과 test.txt에 출력된 것을 확인하였다.
3. exit 모드는 프로그램을 종료하는 것으로, 전체 프로그램을 감싸는 while문의 조건이 state인데 x를 입력하면 state=0이 된다. 따라서 더 이상 while문이 돌지 않고 프로그램이 종료된다.
1. 입출력 텍스트 파일
2. 입력모드
3. 출력모드
4. 출력 결과
소스코드
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#define MAXLINE 4096
#define STDOUT_FILENO 1
void client(int, int), server(int, int);
int main(int argc, char *argv[]){
int pipe1[2], pipe2[2];
pid_t childpid;
pipe(pipe1);
pipe(pipe2);
if((childpid=fork())==0){
close(pipe1[1]);
close(pipe2[0]);
server(pipe1[0],pipe2[1]);
exit(0);}
close(pipe1[0]);
close(pipe2[1]);
client(pipe2[0],pipe1[1]);
waitpid(childpid, NULL, 0);
exit(0);}
void client(int readfd, int writefd){
size_t len;
size_t n;
char buff[MAXLINE];
char mode;
int num;
int state;
char buffer[255];
state=1;
while(state){
printf("\nPlease input : Read 'r' / Write 'w' / Exit 'x'\n");
printf("Input (r,w,x) : ");
scanf("%c",&mode);
write(writefd, &mode, 1);
fgets(buff, MAXLINE, stdin);
switch(mode){
case 'r':
printf("Please input bytes : ");
scanf("%d",&num);
write(writefd, &num, 1);
fgets(buff, MAXLINE, stdin);
printf("Please input path : ");
fgets(buff, MAXLINE, stdin);
len = strlen(buff);
if(buff[len-1] == '\n')
len--;
write(writefd, buff, len);
if((n=read(readfd, buff, MAXLINE))>0)
write(STDOUT_FILENO, buff, num);
break;
case 'w':
printf("Please input path : ");
fgets(buff, MAXLINE, stdin);
len = strlen(buff);
if(buff[len-1] == '\n')
len--;
write(writefd, buff, len);
printf("Please input string : ");
fgets(buff, MAXLINE, stdin);
len = strlen(buff);
if(buff[len-1] == '\n')
len--;
write(writefd, buff, len);
printf("input string is %s",buff);
break;
case 'x':
state = 0;
break;
default : printf("invalid input\n");
break;}}}
void server(int readfd, int writefd){
int fd;
size_t n;
char buff[MAXLINE+1];
int num;
char mode;
int len;
int state;
state=1;
while(state){
read(readfd, &mode, 1);
switch(mode){
case 'r':
read(readfd, &num, 1);
if((n=read(readfd, buff, MAXLINE))==0){
printf("end-of-file");
exit(0);}
buff[n]='\0';
if((fd=open(buff,O_RDONLY))<0){
snprintf(buff+n, sizeof(buff)-n, ": can't open, %s\n", strerror(errno));
n=strlen(buff);
write(writefd, buff, n);}
if((n=read(fd, buff, MAXLINE))>0)
write(writefd,buff,n);
close(fd);
break;
case 'w' :
if((n=read(readfd, buff, MAXLINE))==0){
printf("end-of-file");
exit(0);}
buff[n]='\0';
if((fd=open(buff, O_WRONLY | O_CREAT))<0){
snprintf(buff+n, sizeof(buff)-n, ": can't write, %s\n", strerror(errno));
n=strlen(buff);
write(writefd, buff, n);}
if((n=read(readfd, buff, MAXLINE))>0)
buff[n] = '\n';
write(fd, buff, n);
sprintf(buff,"%d",n);
len = strlen(buff);
write(writefd, buff, len+1);
close(fd);
break;
case 'x' :
state = 0;
break;
default : printf("invalid input\n");
break;
}
}}
'Programming > Linux' 카테고리의 다른 글
32bit 서버에 날짜타입 저장하려고 할 때 에러 (0) | 2019.06.15 |
---|---|
크론탭(crontab) 사용법 (0) | 2018.04.21 |
리눅스 50가지 팁 (0) | 2018.04.21 |
리눅스 vi 명령어 모음 (0) | 2018.04.19 |
CentOS7 GUI 모드로 설치하기(Hiper-V to a Virtual Machine) (0) | 2018.03.19 |