进程间共享 命名管道FIFO

#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

发布了95 篇原创文章 · 获赞 14 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/ding283595861/article/details/105285669
今日推荐