반응형
IPC를 위한 방법으로 파이프,메세지큐,세마포어,소켓등이 있다. 개발하려는 프로그램의 방향에따라 적적한 방식을 택하면 된다.
그 중 소켓을 이용한 IPC는 기존의 네트워크 통신 방식과 동일하다.(어짜피 네트워크 소켓도 프로세스간의 통신을 위한 것이기 때문에) 그래서 API사용에 있어서 좀더 익숙하고 기존의 네트워크 방식을 로컬방식으로 옮길때 코드상의 큰 수정없이 바로 적용가능하다. 그리고 양방향 통신을 위해 파이프방식 처럼 길을 두개 열어줄 필요가 없이 양방향 통신이 가능하다. 어느정도 규모가 있는 프로그램은 소켓을 이용하기를 추천하고 있다.(아마도 대부분 서버-클라이언트 구조라서 그러는 것 같음.) 뿐만아니라 로컬에서의 통신이기 때문에 UDP방식을 사용하더라도 패킷 유실의 걱정도 없다.
기존의 네트워크 상에서 소켓 통신과 달라지는 점은 sock_addr_in 구조체를 sock_addr_un으로 변경해주고 속성을 AF_INET을 AF_UNIX로 변경해주면 된다. +소켓 통신을 하기 위한 파일 경로가 필요하다. (아래의 예제에서는 앱이 실행되는 현재 경로의 test_server라는 파일을 사용한다.)
예제 코드
[Sever]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | #include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<arpa/inet.h> #include<sys/types.h> #include<sys/un.h> #define BUF_SIZE 1024 #define FILE_SERVER "./test_server"//file path int main(void){ int server_socket; int client_socket; int client_addr_size; int option; struct sockaddr_un server_addr; struct sockaddr_un client_addr; char buff_rcv[BUF_SIZE]; char buff_snd[BUF_SIZE]; if(!access(FILE_SERVER, F_OK))//if file exist unlink(FILE_SERVER); server_socket = socket(AF_UNIX, SOCK_STREAM, 0);//create unix socket(TCP) if(server_socket == -1){ printf("server socket error!\n"); exit(1); } memset(&server_addr, 0, sizeof(server_addr)); server_addr.sun_family = AF_UNIX; strcpy(server_addr.sun_path, FILE_SERVER); if(bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)) ==-1){ printf("bind error!\n"); exit(1); } while(1){ if(listen(server_socket, 5) == -1){ printf("listen error! \n"); exit(1); } client_addr_size = sizeof(client_addr); client_socket = accept(server_socket, (struct sockaddr*)&client_addr, &client_addr_size); if(client_socket == -1){ printf("accept failed!\n"); exit(1); } read(client_socket, buff_rcv, BUF_SIZE); printf("received msg : %s\n",buff_rcv); strcpy(buff_snd,"ACK"); write(client_socket, buff_snd, strlen(buff_snd)+1); close(client_socket); } return 0; } | cs |
[Client]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | #include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<arpa/inet.h> #include<sys/types.h> #include<sys/un.h> #define BUFF_SIZE 1024 #define FILE_SERVER "./test_server"//file path int main(void){ int client_socket; char * msg = "Hello World!"; struct sockaddr_un server_addr; char buff[BUFF_SIZE]; client_socket = socket(AF_UNIX, SOCK_STREAM, 0); if(client_socket == -1){ printf("socket create fail!\n"); exit(1); } memset(&server_addr, 0, sizeof(server_addr)); server_addr.sun_family = AF_UNIX; strcpy(server_addr.sun_path, FILE_SERVER); if(connect(client_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1){ printf("connect fail!\n"); exit(1); } write(client_socket, msg, strlen(msg)+1); read(client_socket, buff, BUFF_SIZE); printf("recv msg from server : %s\n",buff); close(client_socket); return 0; } | cs |
반응형
'리눅스' 카테고리의 다른 글
__attribute__ ((visibility("default"))) 관련 (0) | 2020.09.13 |
---|---|
[Linux] Daemon Process란? (0) | 2018.03.25 |
[glib] 메인루프 (0) | 2018.03.04 |
리눅스 signal (0) | 2018.02.17 |
pthread에서 메모리 침범과 pthread_cancel (1) | 2018.01.21 |