#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <pthread.h>
#include <sys/types.h>
#include <errno.h>
#include <string.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/select.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
class CSocketIPCServer;
class CSocketIPCClient;
class CSocketIPCServer
{
public:
int32_t create(const char *sock_name);
int32_t copy_data_to_usr_buf(char *usr_buf);
static void *socket_ipc_server_thread_entry(void *argv);
CSocketIPCServer();
~CSocketIPCServer();
private:
pthread_mutex_t m_lock;
char m_sock_name[64];
int32_t m_connect_fd;
struct sockaddr_un m_sockaddr;
char *m_received_data_buf;
int32_t m_received_data_len;
};
class CSocketIPCClient
{
public:
int32_t create(const char *sock_name);
int32_t send_to_server(char *data_buf, int32_t data_len);
CSocketIPCClient();
~CSocketIPCClient();
private:
char m_sock_name[64];
int32_t m_connect_fd;
struct sockaddr_un m_sockaddr;
};
#define MAX_CLIENT_NUMBER (5)
#define MAX_RECEIVE_BUF_LEN (128*1024)
#define SELECT_TIME_OUT_TIME 10
/******** class defination ********/
CSocketIPCServer::CSocketIPCServer()
{
m_lock = PTHREAD_MUTEX_INITIALIZER;
memset(&m_sock_name, 0x0, sizeof(m_sock_name));
m_connect_fd = -1;
memset(&m_sockaddr, 0x0, sizeof(m_sockaddr));
m_received_data_buf = NULL;
m_received_data_len = 0;
}
CSocketIPCServer::~CSocketIPCServer()
{
if(m_received_data_buf)
{
delete []m_received_data_buf;
m_received_data_buf = NULL;
}
}
void * CSocketIPCServer::socket_ipc_server_thread_entry(void *argv)
{
fd_set rfds;
CSocketIPCServer *ipc_server = (CSocketIPCServer *)(argv);
struct timeval timeout;
/*process client requirement*/
while(1)
{
FD_ZERO(&rfds);
FD_SET(ipc_server->m_connect_fd, &rfds);
timeout.tv_sec = SELECT_TIME_OUT_TIME;
timeout.tv_usec = 0;
switch(select(ipc_server->m_connect_fd+1, &rfds, NULL, NULL, &timeout))
{
case -1:
printf("[%s]ERROR: ipc socket select error\n", __FUNCTION__);
close(ipc_server->m_connect_fd);
return NULL;
case 0:
printf("[%s]WARNING: ipc socket server select timeout\n", __FUNCTION__);
break;
default:
if(FD_ISSET(ipc_server->m_connect_fd, &rfds))
{
pthread_mutex_lock(&ipc_server->m_lock);
ipc_server->m_received_data_len = read(ipc_server->m_connect_fd, ipc_server->m_received_data_buf, MAX_RECEIVE_BUF_LEN);
pthread_mutex_unlock(&ipc_server->m_lock);
}
}
}
close(ipc_server->m_connect_fd);
return NULL;
}
int32_t CSocketIPCServer::create(const char *sock_name)
{
char sock_path_name[64] = {0};
static pthread_t m_socket_ipc_server_tid;
if(!sock_name || strlen(sock_name) > 63)
{
printf("[%s]ERROR: input socket name is NULL or name is too long\n", __FUNCTION__);
return -1;
}
/*allocate receive buffer memory*/
if(!m_received_data_buf)
{
m_received_data_buf = new char[MAX_RECEIVE_BUF_LEN];
}
mkfifo(sock_path_name, 0777);
sprintf(sock_path_name, "/tmp/%s.fifo", sock_name);
m_connect_fd = open(sock_path_name, O_RDWR|O_NONBLOCK , 0777);
if(m_connect_fd < 0)
{
printf("ipc server %s open failure\n", sock_path_name);
return -1;
}
fcntl(m_connect_fd, F_SETPIPE_SZ,MAX_RECEIVE_BUF_LEN);
/*create server process thread*/
if(pthread_create(&m_socket_ipc_server_tid, NULL, socket_ipc_server_thread_entry, (void *)this) < 0)
{
printf("[%s]ERROR: fail to create socket_ipc_server_thread\n", __FUNCTION__);
return -1;
}
pthread_setname_np(m_socket_ipc_server_tid, "sock_ipc_srv");
pthread_detach(m_socket_ipc_server_tid);
printf("[%s]INFO: SocketIPCServer %s has created\n", __FUNCTION__, sock_name);
return 0;
}
int32_t CSocketIPCServer::copy_data_to_usr_buf(char *usr_buf)
{
int32_t data_len = 0;
pthread_mutex_lock(&m_lock);
if(m_received_data_len > 0)
{
data_len = m_received_data_len;
memcpy(usr_buf, m_received_data_buf, m_received_data_len);
m_received_data_len = 0;
}
pthread_mutex_unlock(&m_lock);
return data_len;
}
/************************************************/
/* below is CSocketIPCClient */
/************************************************/
CSocketIPCClient::CSocketIPCClient()
{
memset(&m_sock_name, 0x0, sizeof(m_sock_name));
m_connect_fd = -1;
memset(&m_sockaddr, 0x0, sizeof(m_sockaddr));
}
CSocketIPCClient::~CSocketIPCClient()
{
}
int32_t CSocketIPCClient::create(const char *sock_name)
{
char sock_path_name[64] = {0};
sprintf(sock_path_name, "/tmp/%s.fifo", sock_name);
mkfifo(sock_path_name, 0777);
m_connect_fd = open(sock_path_name, O_RDWR|O_NONBLOCK , 0777);
if(m_connect_fd < 0)
{
printf("ipc client %s open failure\n", sock_path_name);
return -1;
}
fcntl(m_connect_fd, F_SETPIPE_SZ,MAX_RECEIVE_BUF_LEN);
return 0;
}
int32_t CSocketIPCClient::send_to_server(char *data_buf, int32_t data_len)
{
int32_t nwrite = 0;
if(-1 == m_connect_fd)
{
printf("[%s]ERROR: socket is not connected\n", __FUNCTION__);
return -1;
}
nwrite = write(m_connect_fd, data_buf, data_len);
return nwrite;
}
/******** global variables ********/
static CSocketIPCServer m_socket_ipc_server;
static CSocketIPCClient m_socket_ipc_client;
/********extern functions ********/
int32_t socket_ipc_server_init(const char *sock_name)
{
m_socket_ipc_server.create(sock_name);
return 0;
}
int32_t socket_ipc_server_copy_received_data(char *usr_buf)
{
int32_t copy_data_len = 0;
if(!usr_buf)
{
printf("[%s]ERROR: input usr_buf is NULL\n", __FUNCTION__);
return -1;
}
copy_data_len = m_socket_ipc_server.copy_data_to_usr_buf(usr_buf);
return copy_data_len;
}
int32_t socket_ipc_client_init(const char *sock_name)
{
return m_socket_ipc_client.create(sock_name);
}
int32_t socket_ipc_send_to_server(char *send_buf, int32_t buf_len)
{
if(!send_buf)
{
printf("[%s]ERROR: send buf is NULL\n", __FUNCTION__);
return -1;
}
m_socket_ipc_client.send_to_server(send_buf, buf_len);
return 0;
}
提供动态库接口,进程间可以相互通信
#ifndef _SOCKET_IPC_H_
#define _SOCKET_IPC_H_
#ifdef __cplusplus
extern "C" {
#endif
extern int32_t socket_ipc_server_init(const char *sock_name);
extern int32_t socket_ipc_server_copy_received_data(char *usr_buf);
extern int32_t socket_ipc_client_init(const char *sock_name);
extern int32_t socket_ipc_send_to_server(char *send_buf, int32_t buf_len);
#ifdef __cplusplus
}
#endif
#endif