==========================================================================================
NETWORK
==========================================================================================
<NETWORK>
==2차 : 클라이언트들간 대화 가능하도록 수정
-IPC(Inter Process Communication) : 프로세스간 통신
=IPC종류
-파이프 : 단방향
-메시지 큐
-네임드 파이프
-공유 메모리
-...
=파이프
int fd[2];
pipe(fd);
=익명 파이프
-구심점 : 내부 변수
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h>
int main() {
int fd[2]; int buf; int i =0; int pid;
if(pipe(fd) < 0) { perror("pipe error : "); return 1; }
if((pid = fork()) <0) { return 1; } else if(pid ==0) { close(fd[0]); while(1) { i++; write(fd[1], (void *)&i, sizeof(i)); sleep(1); } } else { close(fd[1]); while(1) { read(fd[0], (void *)&buf, sizeof(buf)); printf("> %d\n", buf); } }
return 0; } |


=네임드 파이프
-소스를 완전 분리시 연결할 방법 없다
-구심점 : 중간(Z.TXT)에 가교 요청(ex)- A에서 Z.TXT 열고 B에서도 Z.TXT를 열어 A에서 Z에 내용을 쓰면 B에서 사용 가능)
: mkfifo() => first in first out
-tmp 확인


-확인(구심점 : myfifo_r)
ls -al /tmp/myfifo_r
d(directory) -> p(pipe)


<echoserverpipe.c>
#include <sys/types.h> #include <sys/stat.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> #include <string.h>
#define MAXLINE 1024 int main(int argc, char **argv) { int rfd, wfd; char buf[MAXLINE];
mkfifo("/tmp/myfifo_r", S_IRUSR | S_IWUSR); mkfifo("/tmp/myfifo_w", S_IRUSR|S_IWUSR); if((rfd = open("/tmp/myfifo_r", O_RDWR)) == -1) { perror("rfd error"); return 1; }
if((wfd = open("/tmp/myfifo_w", O_RDWR)) == -1) { perror("wfd error"); return 2; } while(1) { memset(buf, 0x00, MAXLINE); if(read(rfd, buf, MAXLINE) < 0) { perror("Read Error"); return 3; } printf("Read : %s", buf); write(wfd, buf, MAXLINE); lseek(wfd, 0, SEEK_SET); }
return 0; } |
<echoclientpipe.c>
#include <sys/types.h>
#include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> #include <string.h>
#define MAXLINE 1024 int main(int atgc, char **arcv) { int rfd, wfd; char buf[MAXLINE];
rfd = open("/tmp/myfifo_w", O_RDWR); if(rfd < 0) { perror("read open error\n"); return 1; } wfd = open("/tmp/myfifo_r", O_RDWR); if(wfd < 0) { perror("write open error\n"); return 1; } while(1) { printf("> "); fflush(stdout); memset(buf, 0x00, MAXLINE); if(read(0, buf, MAXLINE) < 0) { printf("error\n"); return 1; } if(strncmp(buf, "quit\n", 5) == 0) { break; } write(wfd, buf, strlen(buf)); read(rfd, buf, MAXLINE); printf("Server -> %s", buf); } close(wfd); close(rfd); return 0; } |




=네임드파이프단점 : 클라이언트 수 만큼 파이프 만들어야 함 => 채팅용으로는 부적합
==유닉스 도메인 소켓
파일 경로
구심점 : 소켓파일
: sockaddr_in -> sockaddr_un
: d(directory) -> s(socket)
: access() : 해당 파일 읽을 수 있는지 체크
<echoserver_udomain.c>
#include <sys/types.h> #include <sys/stat.h> #include <sys/socket.h> #include <sys/un.h> #include <stdio.h> #include <string.h> #include <unistd.h>
#define MAXLINE 1024
int main(int argc, char ** argv) { int listen_fd; int client_fd; socklen_t addrlen; int readn; char buf[MAXLINE]; struct sockaddr_un client_addr; struct sockaddr_un server_addr;
if(argc !=2) { printf("Usage : %s [socket file name] \n", argv[0]); return 1; } if(access(argv[1], F_OK) ==0) { unlink(argv[1]); }
if((listen_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { perror("Error : socket"); return 2; }
memset((void *)&server_addr, 0x00, sizeof(server_addr)); server_addr.sun_family = AF_UNIX; strncpy(server_addr.sun_path, argv[1], strlen(argv[1]));
if(bind(listen_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) { perror("Error : bind"); return 3; }
if(listen(listen_fd, 5) ==-1) { perror("Error : listen"); return 4; }
while(1) { memset((void *)&client_addr, 0x00, sizeof(client_addr)); printf("accept wait\n"); client_fd = accept(listen_fd, (struct sockaddr *)&client_addr, &addrlen);
while(1) { if(client_fd ==-1) { printf("Accept Error "); return 0; } memset(buf, 0x00, MAXLINE); readn = read(client_fd, buf, MAXLINE); if(readn ==0) break; printf("==> %s", buf); write(client_fd, buf, strlen(buf)); } } return 0; }
|
<echoclient_udomain.c>
#include <sys/types.h> #include <sys/stat.h> #include <sys/socket.h> #include <sys/un.h> #include <stdio.h> #include <string.h> #include <unistd.h>
#define MAXLINE 1024
int main(int argc, char **argv) { int sockfd; int clilen; char buf[MAXLINE]; struct sockaddr_un sock_addr;
if(argc !=2) { printf("Usage : %s [socket file name]\n", argv[0]); return 1; }
if(access(argv[1], R_OK) == -1) { printf("socket File access error\n"); return 2; }
sockfd =socket(AF_UNIX, SOCK_STREAM, 0);
memset((void *)&sock_addr, 0x00, sizeof(sock_addr)); sock_addr.sun_family = AF_UNIX; strncpy(sock_addr.sun_path, argv[1], strlen(argv[1])); clilen = sizeof(sock_addr); connect(sockfd, (struct sockaddr *)&sock_addr, clilen);
while(1) { memset(buf, 0x00, MAXLINE); read(0, buf, MAXLINE); if(strncmp(buf, "quit\n", 5) ==0) { break; } write(sockfd, buf, strlen(buf)); read(sockfd, buf, MAXLINE); printf("server -> %s", buf); } return 0; } |




(적은양의 데이터를 많은 프로세스에서 사용시)
-파일 소켓 단점 : 다중접속은되나 성능이 떨어짐
==공유메모리
: shmget() :
: shmat()
: shmdt()
: shmctl() : 관리
-확인
: ipcs -m


-
<shm_procuder.c>
#include <sys/ipc.h> #include <sys/shm.h> #include <string.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h>
int main(int argc, char **argv) { int shmid;
int *cal_num; void *shared_memory = NULL;
shmid = shmget((key_t) 1234, sizeof(int), 0666|IPC_CREAT); if(shmid == -1) { perror("shmget failed : "); exit(0); }
shared_memory = shmat(shmid, NULL, 0); if(shared_memory == (void *)-1) { perror("shmat failed : "); exit(0); }
cal_num = (int *)shared_memory; while(1) { *cal_num = *cal_num +2; sleep(1); } return 0; } |
<shm_consumer.c>
#include <sys/ipc.h> #include <sys/shm.h> #include <string.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h>
int main(int argc, char ** argv) { int shmid;
int *cal_num; void *shared_memory = NULL;
shmid =shmget((key_t)1234, sizeof(int), 0); if(shmid == -1) { perror("shmget failed : "); exit(0); }
shared_memory = shmat(shmid, NULL, 0); if(shared_memory == (void *)-1) { perror("shmat failed : "); exit(0); }
cal_num = (int *)shared_memory;
while(1) { sleep(1); printf("Read Dta : %d\n", *cal_num); } return 0; } |


=
1. 멀티 P : PROCESS 여러개
2. 멀티 T : PROCESS 1개 THREAD 여러개
3. 다중 입출력 : PROCESS 1개