這裡提供一個小範例, 將unix socket api再包一層, 讓開發程式時能更容易的達成IPC目的.
my_unix_socket.h
#ifndef __MY_UNIX_SOCKET_H__ #define __MY_UNIX_SOCKET_H__ int create_listener(char* name, void* funp(char*)); int send_to_listener(char* app_name, void* buf, int buf_size); #endif /* __MY_UNIX_SOCKET_H__ */
my_unix_socket.c
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <sys/un.h> #define MAX_BUF_SIZE (1024) static void first_handler(int fd, char* buf) { int connected_fd; struct sockaddr_un from; int lenfrom = sizeof(from); bzero(&from, sizeof(from)); if ((connected_fd = accept(fd, (struct sockaddr *)&from, &lenfrom)) < 0 ) { printf("accept failed\n"); return; } if (recv(connected_fd, buf, MAX_BUF_SIZE, 0) < 0) { printf("recv failed\n"); return; } close(connected_fd); return; } int create_listener(char* name, void* funp(char*)) { int fd, ret=-1; struct sockaddr_un saddr; struct sockaddr_un from; char buf[MAX_BUF_SIZE]; /* open a socket */ if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { printf("socket failed\n"); goto fun_exit; } /* set the addr */ unlink(name); bzero(&saddr, sizeof(saddr)); saddr.sun_family = AF_UNIX; strcpy(saddr.sun_path, name); /* bind socket with addr */ if (bind(fd, (struct sockaddr*)&saddr, sizeof(saddr)) < 0) { printf("bind failed\n"); goto fun_exit; } /* listen fd */ if (listen(fd, 10) < 0) { printf("listen failed\n"); goto fun_exit; } fd_set rset; FD_ZERO(&rset); FD_SET(fd, &rset); while (1) { select(fd+1, &rset, NULL, NULL, NULL); if (FD_ISSET(fd, &rset)) { first_handler(fd, buf); funp(buf); } } ret = 0; fun_exit: if (fd>0) close(fd); return ret; } int send_to_listener(char* app_name, void* buf, int buf_size) { int fd, ret=-1; struct sockaddr_un saddr; if (buf_size > MAX_BUF_SIZE) { printf("The max message size is %d\n", MAX_BUF_SIZE); goto fun_exit; } /* open a socket */ if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { printf("socket failed\n"); goto fun_exit; } /* set the saddr */ bzero(&saddr, sizeof(saddr)); saddr.sun_family = AF_UNIX; strcpy(saddr.sun_path, app_name); /* connect to server */ if (connect(fd, (struct sockaddr*)&saddr, sizeof(saddr)) < 0) { printf("connect failed\n"); goto fun_exit; } /* send data */ if (send(fd, buf, buf_size, 0) < 0) { printf("send failed\n"); goto fun_exit; } ret = 0; fun_exit: if (fd>0) close(fd); return ret; }
兩隻簡單的應用程式:
server.c
#include <stdio.h> void my_recv(char* buf) { printf("%s,%s: %s\n", __FILE__, __FUNCTION__, buf); } int main() { create_listener("my_server", my_recv); }
client.c
#include <stdio.h> #include "my_unix_socket.h" int main() { char buf[] = "hello unix socket"; send_to_listener("my_server", buf, sizeof(buf)); }
參考資料:
[1] Unix Sockets
[2] Unix domain sockets vs. internet sockets
沒有留言:
張貼留言