Named pipe를 사용한 프로세스 간 양방향 채팅 프로그램

2023. 6. 9. 00:55시스템프로그래밍

이 글에서는 Named pipe를 사용하여 프로세스 간의 양방향 채팅 프로그램을 구현해보았다.

 

Ubuntu Linux 환경에서 vim 에디터로 c언어를 사용하여 구현을 했다.

 

이 프로그램은 서버 - 클라이언트 간 1대1 채팅을 진행한다.

 

그래서 서버가 메세지를 보내면 클라이언트에서 메세지가 올 때까지 대기를 하게 된다.

 

클라이언트는 서버가 메세지가 오면 메세지를 확인하고 서버에게 메세지를 전송한다.

 

그 후 클라이언트는 서버로부터 메세지가 올 때까지 대기하게 된다.

 

여기서는 Named pipe를 두 개를 두고 하나는 서버에서 클라이언트로의 전송용.

 

다른 하나는 클라이언트에서 서버로의 전송용으로 동작을 하게 된다.

 

동작 설명 그림

 

프로세스 1 코드
1 #include<fcntl.h>
2 #include<stdio.h>
3 #include<stdlib.h>
4 #include<string.h>
5 #include<unistd.h>
6 #include<sys/types.h>
7 #include<sys/stat.h>
8 #define SIZE 1000
9
10 int main(){
11 int pd, pd2, n;
12 char msg[SIZE] = "연결 되었습니다.";
13
14 if(mkfifo("./EX-FIFO", 0666)==-1){// 메세지 송신용 파일
15 perror("mkfifo");
16 exit(1);
17 }
18 if(mkfifo("./EX-FIFO2", 0666)==-1){// 수신용 파일
19 perror("mkfifo2");
20 exit(1);
21 }
22
23 if((pd = open("./EX-FIFO",O_WRONLY))==-1){
24 perror("open");
25 exit(1);
26 }
27 if((pd2 = open("./EX-FIFO2",O_RDONLY))==-1){
28 perror("open");
29 exit(1);
30 }
31 while(1){
32 // 클라이언트로 메세지 보내기
33 write(1,"to client :",11);
34 fgets(msg, SIZE, stdin);
35 n=write(pd, msg, strlen(msg)+1);
36 if(n==-1){
37 perror("write");
38 exit(1);
39 }
40
41 // 클라이언트에서 메세지 받기
42 write(1,"From client :",13);
43 n=read(pd2, msg, 80);
44 write(1, msg, n);
45 if(n == -1){
46 perror("read");
47 exit(1);
48 }
49 write(1,"\n",1);
50
51 }
52
53 close(pd);
54 close(pd2);
55 return 0;
56 }
 
프로세스 2 코드
1 #include<fcntl.h>
2 #include<stdio.h>
3 #include<stdlib.h>
4 #include<string.h>
5 #include<unistd.h>
6 #include<sys/types.h>
7 #include<sys/stat.h>
8 #define SIZE 1000
9
10 int main(){
11 int pd, pd2, n;
12 char inmsg[SIZE];
13
14 if((pd = open("./EX-FIFO",O_RDONLY))==-1){// 수신용 파일
15 perror("open");
16 exit(1);
17 }
18 if((pd2 = open("./EX-FIFO2",O_WRONLY))==-1){// 송신용 파일
19 perror("open");
20 exit(1);
21 }
22
23 while(1){
24 // 서버에서 메세지 받기
25 write(1, "From Server :",13);
26 n=read(pd, inmsg, 80);
27 write(1, inmsg, n);
28 if(n==-1){
29 perror("read");
30 exit(1);
31 }
32 write(1,"\n",1);
33
34 // 서버로 메세지 보내기
35 write(1,"to server :",11);
36 fgets(inmsg, SIZE, stdin);
37 n=write(pd2, inmsg, strlen(inmsg)+1);
38 if(n==-1){
39 perror("write");
40 exit(1);
41 }
42 }
43
44 close(pd);
45 close(pd2);
46 return 0;
47 }
 

( while(1) 로 무한 루프에 빠져서 동작하기 때문에 ctrl+c를 눌러서 프로세스에 SIGINT를 전달하여 종료할 수 있습니다. )

 

( 추가로 생성된 NAMED PIPE를 제거하는 동작을 진행하지 않아서 동작 시 rm 명령어를 이용하여 생성된 파이프를 삭제해 주어야 합니다. )

 

실행 결과