TCP 네트워크 프로그래밍 - 2 (IPC)
2019. 7. 23. 12:00ㆍ드론
socket을 통한 IPC는 호스트 전용 도메인(Unix domain socket) 혹은 인터넷 도메인 상에서 loopback addr(Local addr)를 사용하게 된다

This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <unistd.h> | |
#include <sys/un.h> | |
#include <sys/types.h> | |
#include <sys/socket.h> | |
static void print_usage(char *progname) | |
{ | |
printf("usage : %s [server|client]\n", progname); | |
} | |
static int do_server(void) | |
{ | |
/* | |
socket | |
bind | |
listen | |
accept | |
write/read | |
*/ | |
int ret, sockfd, clifd; | |
struct sockaddr_un servaddr; | |
char buf[128]; | |
/* | |
Address format | |
A UNIX domain socket address is represented in the following structure: | |
struct sockaddr_un { | |
sa_family_t sun_family; | |
char sun_path[108]; | |
}; | |
*/ | |
sockfd = socket(AF_UNIX, SOCK_STREAM, 0); | |
if(sockfd < 0) { | |
perror("socket"); | |
return -1; | |
} | |
memset(&servaddr, 0, sizeof(servaddr)); | |
servaddr.sun_family = AF_UNIX; | |
strcpy(servaddr.sun_path, "./sockpath"); | |
ret = bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); | |
if(ret < 0) { | |
perror("bind"); | |
close(sockfd); | |
return -1; | |
} | |
ret = listen(sockfd, 8); | |
if(ret < 0) { | |
perror("listen"); | |
close(sockfd); | |
return -1; | |
} | |
// socket IPC에서는 클라이언트 정보를 받아올 필요는 없다 | |
clifd = accept(sockfd, NULL, NULL); | |
if(clifd < 0) { | |
perror("accept"); | |
close(sockfd); | |
return -1; | |
} | |
memset(buf, 0, sizeof(buf)); | |
// recv는 clifd를 socket fd로 전 | |
recv(clifd, buf, sizeof(buf), 0); | |
printf("Received data : %s\n", buf); | |
close(sockfd); | |
close(clifd); | |
return 0; | |
} | |
static int do_client(void) | |
{ | |
int sockfd, ret; | |
struct sockaddr_un cliaddr; | |
char buf[128]; | |
sockfd = socket(AF_UNIX, SOCK_STREAM, 0); | |
if(sockfd < 0) { | |
perror("socket"); | |
return -1; | |
} | |
memset(&cliaddr, 0, sizeof(cliaddr)); | |
cliaddr.sun_family = AF_UNIX; | |
strcpy(cliaddr.sun_path, "./sockpath"); | |
ret = connect(sockfd, (struct sockaddr *)&cliaddr, sizeof(cliaddr)); | |
if(ret < 0) { | |
perror("connect"); | |
close(sockfd); | |
return -1; | |
} | |
memset(buf, 0, sizeof(buf)); | |
snprintf(buf, sizeof(buf), "This is msg from sock_stream"); | |
ret = send(sockfd, buf, sizeof(buf), 0); | |
if(ret < 0) { | |
perror("send"); | |
close(sockfd); | |
return -1; | |
} | |
close(sockfd); | |
return 0; | |
} | |
int main(int argc, char **argv) | |
{ | |
int ret; | |
if(argc < 2) { | |
print_usage(argv[0]); | |
return -1; | |
} | |
if(!strcmp(argv[1], "server")) { | |
ret = do_server(); | |
} else if(!strcmp(argv[1], "client")) { | |
ret = do_client(); | |
} else { | |
print_usage(argv[0]); | |
} | |
return 0; | |
} |
'드론' 카테고리의 다른 글
polling 방식의 다중 클라이언트 echo (0) | 2019.07.24 |
---|---|
UDP 네트워크 프로그래밍 - 3 (IPC) (0) | 2019.07.23 |
socket 함수의 3번째 인자 (0) | 2019.07.23 |
send/recv partial Error 방지하는 법 (0) | 2019.07.23 |
tcp bind 에러 원인과 해결법과 SO_REUSEADDR (1) | 2019.07.22 |