這裡提供一個小範例, 將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
沒有留言:
張貼留言