리눅스는 유닉스 소켓을 이용하여 프로세스끼리 파일 디스크립트를 보내주고 받을 수 있다.
아래 예제는 뼈대만 존재한다. 예외나 기타 처리는 없다.
뼈대에 살을 붙이는 형태로 사용 할 것이다.
자세한 설명은 나중에.. 시간이 있다면...
sender.c - 이 예제에서는 sender 프로세스가 자신의 표준출력 디스크립트를 전송 |
#include<stdio.h> #include<stdlib.h> #include<sys/types.h> #include<sys/socket.h> #include<unistd.h> #include<sys/un.h> int main(int argc,char **args) { int sc; struct sockaddr_un addr; int z; int fd; sc = socket(PF_LOCAL,SOCK_STREAM,0); if(sc < 0) { return -1; } memset(&addr,sizeof(addr),0); addr.sun_family = AF_LOCAL; strncpy(addr.sun_path,"zSOCKET-SERVER", sizeof(addr.sun_path) -1); addr.sun_path[0] = 0; z = connect(sc,&addr,sizeof(addr)); if(z < 0) { return -1; } struct msghdr msgh; struct iovec iov[1]; struct cmsghdr *cmsgp = NULL; char buf[CMSG_SPACE(sizeof(int))]; int er=99; // msgh.msg_name = &addr; // msgh.msg_namelen = sizeof(addr); msgh.msg_name = NULL; msgh.msg_namelen = 0; msgh.msg_iov = iov; msgh.msg_iovlen = 1; iov[0].iov_base = &er; iov[0].iov_len = sizeof(er); msgh.msg_control = buf; msgh.msg_controllen = sizeof(buf); cmsgp = CMSG_FIRSTHDR(&msgh); cmsgp->cmsg_level = SOL_SOCKET; cmsgp->cmsg_type = SCM_RIGHTS; cmsgp->cmsg_len = CMSG_LEN(sizeof(fd)); //보낼 파일디스크립터 지정 fd = fileno(stdout); *((int *)CMSG_DATA(cmsgp) ) = fd; msgh.msg_controllen = cmsgp->cmsg_len; sendmsg(sc,&msgh,0); close(sc); return 0; } |
recver.c - sender 프로세스가 보낸 파일 디스크립트에 "test" 란 문자열을 쓴다. |
#include<stdio.h> #include<stdlib.h> #include<sys/types.h> #include<sys/socket.h> #include<unistd.h> #include<sys/un.h> #include<string.h> #include<errno.h> int main() { int server_sc; struct sockaddr_un server_addr; struct sockaddr_un client_addr; socklen_t len; int er; server_sc = socket(PF_LOCAL,SOCK_STREAM,0); if(server_sc < 0) { perror(""); return -1; } memset(&server_addr,0,sizeof(server_addr)); server_addr.sun_family = AF_LOCAL; strncpy(server_addr.sun_path,"zSOCKET-SERVER", sizeof(server_addr.sun_path) -1); server_addr.sun_path[0] = 0; er = bind(server_sc,&server_addr,sizeof(server_addr)); if(er < 0) { perror(""); return -1; } listen(server_sc,4); while(1) { int fd; int rlen; len= sizeof(client_addr); fd = accept(server_sc,&client_addr,&len); if(fd < 0) { return -1; }
int recv_fd; struct msghdr msgh; struct iovec iov[1]; struct cmsghdr * cmsgp = NULL; char buf [CMSG_SPACE(sizeof(int))]; char dbuf[80]; int er; memset(&msgh,0,sizeof(msgh)); memset(buf,0,sizeof(buf)); msgh.msg_name = NULL; msgh.msg_namelen = 0; msgh.msg_iov = iov; msgh.msg_iovlen = 1; iov[0].iov_base = &er; iov[0].iov_len = sizeof(er); msgh.msg_control = buf; msgh.msg_controllen = sizeof(buf);
recvmsg(fd,&msgh,0); // printf("recvmsg end iov = %d\n",*((int *)iov[0].iov_base)); for(cmsgp = CMSG_FIRSTHDR(&msgh);cmsgp != NULL ; cmsgp = CMSG_NXTHDR(&msgh,cmsgp)) { printf("for \n"); if(cmsgp->cmsg_level == SOL_SOCKET && cmsgp->cmsg_type == SCM_RIGHTS) {
recv_fd = *((int *)CMSG_DATA(cmsgp)); write(recv_fd,"test",strlen("test")); } } close(fd); } return 0; } |
'학습자료(~2017) > 리눅스' 카테고리의 다른 글
[Network] Bonding , multi Bonding (추가내용) (2) | 2013.06.28 |
---|---|
[Linux] 파일 관련 API 리스트 (0) | 2013.05.31 |
[Linux] RPM package(RPM 만들기 , RPM 패키징) 이모저모 (0) | 2013.04.04 |
[LINUX] Library constructor and destructor functions (라이브러리 생성자, 소멸자 기능 _init , _fini) (0) | 2013.03.21 |
[Linux] path resolution , 경로 분석법 (0) | 2013.03.06 |