TIPC

参考

简介

简介

  • TIPC是爱立信开源的透明进程通信协议,一般用于集群系统中。
  • tipc是基于socket实现的,但是与一般的socket还有所区别
    • 一般的socket 用两个socket的IP地址和端口号标识一对socket的通信,要发送消息必须知道对方在哪台设备上,IP和端口是多少才能发送。
    • TIPC:
      • 内核维护着这样一张路由表,可以根据服务类型去找到对应的socket
      • 创建socket的时候,在内核中注册自己的服务类型
      • 发送端,只需要指定服务类型就可以由内核路由到相应的socket
      • 每台设备都有这样的路由表,他们的信息就能够像普通路由表一样共享到整个集群网络中去,所有设备都可以进行socket查找。

 

代码示例

服务器

  

#define SERVER_TYPE 18888
#define SERVER_INST 17

server_addr.family = AF_TIPC;
server_addr.addrtype = TIPC_ADDR_NAMESEQ;
server_addr.addr.nameseq.type = SERVER_TYPE;
server_addr.addr.nameseq.lower = SERVER_INST;
server_addr.addr.nameseq.upper = SERVER_INST;
server_addr.scope = TIPC_ZONE_SCOPE;

sd = socket(AF_TIPC, SOCK_RDM, 0);

if (0 != bind(sd, (struct sockaddr *)&server_addr, sizeof(server_addr))) {
  printf("Server: failed to bind port name\n");
  exit(1);
}

if (0 >= recvfrom(sd, inbuf, sizeof(inbuf), 0,(struct sockaddr *)&client_addr, &alen)) {
  perror("Server: unexpected message"); } printf("Server: Message received: %s !\n", inbuf); if (0 > sendto(sd, outbuf, strlen(outbuf)+1, 0,(struct sockaddr *)&client_addr, sizeof(client_addr))) {   perror("Server: failed to send"); }

  

客户端

  

// 服务端调用wait_for_server来等待server连上
wait_for_server(SERVER_TYPE, SERVER_INST, 10000); sd = socket(AF_TIPC, SOCK_RDM, 0);
server_addr.family = AF_TIPC; server_addr.addrtype = TIPC_ADDR_NAME; server_addr.addr.name.name.type = SERVER_TYPE; server_addr.addr.name.name.instance = SERVER_INST; server_addr.addr.name.domain = 0; if (0 > sendto(sd, buf, strlen(buf)+1, 0,(struct sockaddr*)&server_addr, sizeof(server_addr))) {   perror("Client: failed to send");   exit(1); } if (0 >= recv(sd, buf, sizeof(buf), 0)) {   perror("Client: unexpected response");   exit(1); }

 

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <getopt.h>
#include <unistd.h>
#include <poll.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <linux/tipc.h>
#include <linux/tipc_config.h>
#include <linux/genetlink.h>
#include <linux/if_packet.h>
#include <linux/if.h>
#include <sys/ioctl.h>
#include <linux/tipc.h>
#define TEST_MSG_SIZE 2048
#define TEST_READ_TIMES 10
#define TEST_MSG_LEN 64*1024
typedef struct tagDmslLogiLinkAddrTipc
{
    int  uiType;
    int  uiInstance;
}TIPC_ADDR_STR;

int dmsGetSockAddr(struct sockaddr* SocketAddr, TIPC_ADDR_STR *pstLogilinkAdds)
{
    struct sockaddr_tipc* addr = (struct sockaddr_tipc*)SocketAddr;

    /*设定监听地址*/
    if((0 == addr)||(0 == pstLogilinkAdds))
    {
        return 10000;
    }


    memset(addr, 0, sizeof(struct sockaddr_tipc));

    addr->family   = AF_TIPC;
    addr->addrtype = TIPC_ADDR_NAME;
    addr->addr.name.name.type = pstLogilinkAdds->uiType;
    addr->addr.name.name.instance = pstLogilinkAdds->uiInstance;
    addr->addr.name.domain = 0;
    addr->scope = 2;

    return 0;
}

 

int main()
{
    int uiRet,stSocket,uiNum,n,i;
    struct sockaddr location_addr, TagSockAddr;
    struct sockaddr_tipc servAddr;
    TIPC_ADDR_STR* pstPortName;
    void *pMsg;
    fd_set  fdReadSet;
    struct timeval  stwait;
    socklen_t addrlen = sizeof(struct sockaddr);
    static  int uiMsgNum = 0;
    char Buf[TEST_MSG_SIZE] ;
    struct msghdr stMsg;
    struct iovec  astIovec[1];
   
    pstPortName = malloc(sizeof(TIPC_ADDR_STR));
    pstPortName->uiType = 0x80000001;
    pstPortName->uiInstance = 130987;

    stSocket = socket(AF_TIPC, SOCK_RDM, 0);
    if (-1 == stSocket)
    {
        perror("socket");
        return -1;
    }

    uiRet = dmsGetSockAddr(&location_addr, pstPortName);
    if(0 != uiRet)
    {
        printf("dmsGetSockAddr Failed 0x%x",uiRet);
        return -1;
    }

    uiRet = bind(stSocket, (__CONST_SOCKADDR_ARG)&location_addr, (socklen_t)sizeof(location_addr));
    if (0 != uiRet)
    {
        printf("bind Failed 0x%x",uiRet);
        return -1;
    }

    pMsg = malloc(TEST_MSG_SIZE);
    if (NULL == pMsg)
    {
        printf("malloc Failed");
        return -1;
    }

    while(1)
    {
        FD_ZERO( &fdReadSet );
        FD_SET(stSocket, &fdReadSet);
        stwait.tv_sec = 0;
        stwait.tv_usec = 10000;

 //       if(select(stSocket + 1, &fdReadSet, (fd_set*)0, (fd_set*)0, &stwait)>0)
        {
//            uiNum = 0;
//            while (uiNum < TEST_READ_TIMES)
            {
                n = recvfrom(stSocket, pMsg, TEST_MSG_LEN, 0, ( __SOCKADDR_ARG)(struct sockaddr_tipc *)&servAddr, (unsigned int *)(size_t*)&addrlen);
                if (n <= 0)
                {
                    continue;
                }
//                uiMsgNum += n / TEST_MSG_SIZE;
                pstPortName->uiType = 0x70000001;
                pstPortName->uiInstance = 130986;
                uiRet = dmsGetSockAddr(&TagSockAddr, pstPortName);
                if(0 != uiRet)
                {
                    printf("dmsGetSockAddr Failed 0x%x",uiRet);
                    return -1;
                }
//                uiNum++;
//                for(i = 0;i < uiMsgNum;i++)
                {
//                    pBuf = malloc(TEST_MSG_SIZE);
//                    memset(pBuf, 0, TEST_MSG_SIZE);
                    sendto(stSocket, (void*)Buf, TEST_MSG_SIZE, 0,
                        (struct sockaddr*)&TagSockAddr, sizeof(TagSockAddr));
//                    printf("send msg num is %d\n",i);
                }

            }
        }
    }
   
    return 0;
}

 

 

client.c

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <getopt.h>
#include <unistd.h>
#include <poll.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <linux/tipc.h>
#include <linux/tipc_config.h>
#include <linux/genetlink.h>
#include <linux/if_packet.h>
#include <linux/if.h>
#include <sys/ioctl.h>
#include <linux/tipc.h>
#include <assert.h>
#include <pthread.h>


#define TEST_MSG_LEN 64*1024
#define TEST_MSG_SIZE 2048
typedef struct tagDmslLogiLinkAddrTipc
{
    int  uiType;
    int  uiInstance;
}TIPC_LOGI_ADDR_STR;

//typedef void *( * OSAL_LINUX_TASK_ENTRY )( VOS_VOID * );

int stSocket;

int dmsGetSockAddr(struct sockaddr* SocketAddr, TIPC_LOGI_ADDR_STR *pstLogilinkAdds)
{
    struct sockaddr_tipc* addr = (struct sockaddr_tipc*)SocketAddr;

    /*设定监听地址*/
    if((0 == addr)||(0 == pstLogilinkAdds))
    {
        return -1;
    }


    memset(addr, 0, sizeof(struct sockaddr_tipc));

    addr->family   = AF_TIPC;
    addr->addrtype = TIPC_ADDR_NAME;
    addr->addr.name.name.type = pstLogilinkAdds->uiType;
    addr->addr.name.name.instance = pstLogilinkAdds->uiInstance;
    addr->addr.name.domain = 0;
    addr->scope = 2;

    return 0;
}

void  RecvProc(void *pThis)
{
    fd_set  fdReadSet;
    struct timeval  stwait;
    int uiNum,n,uiSecd;
    static  int uiMsgNum = 0;
    static struct timeval stEndtimeFei,stStarttimeFei;
    struct sockaddr_tipc servAddr;
    socklen_t addrlen = sizeof(struct sockaddr);
    void *pMsg;
    printf("------------");
    pMsg = malloc(TEST_MSG_SIZE);
    if (NULL == pMsg)
    {
        printf("malloc Failed");
        return ;
    }

    while(1)
    {
        FD_ZERO( &fdReadSet );
        FD_SET(stSocket, &fdReadSet);
        stwait.tv_sec = 0;
        stwait.tv_usec = 10000;

//        if(select(stSocket + 1, &fdReadSet, (fd_set*)0, (fd_set*)0, &stwait)>0)
        {
 //           uiNum = 0;
 //           while (uiNum < TEST_READ_TIMES)
            {
                n = recvfrom(stSocket, pMsg, TEST_MSG_LEN, 0, ( __SOCKADDR_ARG)(struct sockaddr_tipc *)&servAddr, (unsigned int *)(size_t*)&addrlen);
                if (n <= 0)
                {
                    continue;
                }
                if(uiMsgNum == 0)
                {
                    gettimeofday(&stStarttimeFei,NULL);
                }               
//                uiMsgNum += n / TEST_MSG_SIZE;
                uiMsgNum++;
//                printf("recv msg num is %d\n",uiMsgNum);
//                uiNum++;
                if((uiMsgNum%200000) == 0)
                {
                    gettimeofday(&stEndtimeFei,NULL);
                    uiSecd = (stEndtimeFei.tv_sec - stStarttimeFei.tv_sec)*1000 + (stEndtimeFei.tv_usec - stStarttimeFei.tv_usec)/1000 ;
                    printf("The flux is %u\n",200000/uiSecd);
                    gettimeofday(&stStarttimeFei,NULL);
                }
            }
        }
    }

}

int main(int ac, char **av)
{
    pthread_attr_t attr;    /* attributes for thread */
    pthread_t tid;
    void *pThis;
    int uiRet,uiSize,i,j;
    struct sockaddr location_addr, TagSockAddr;
    TIPC_LOGI_ADDR_STR* pstPortName;
    TIPC_LOGI_ADDR_STR* pstDstPortName;
    char Buf[TEST_MSG_SIZE] ;
    struct msghdr stMsg;
    int iNum;

    iNum = atoi(av[1])

    uiSize = TEST_MSG_SIZE;

   
    pstPortName = malloc(sizeof(TIPC_LOGI_ADDR_STR));
    pstDstPortName = malloc(sizeof(TIPC_LOGI_ADDR_STR));
    pstPortName->uiType = 0x70000001;
    pstPortName->uiInstance = 130986;

    stSocket = socket(AF_TIPC, SOCK_RDM, 0);
    if (-1 == stSocket)
    {
        perror("socket");
        exit(1);
    }

    uiRet = dmsGetSockAddr(&location_addr, pstPortName);
    if(0 != uiRet)
    {
        printf("\r\ndmsGetSockAddr Failed 0x%x",uiRet);
        return -1;
    }

    uiRet = bind(stSocket, (__CONST_SOCKADDR_ARG)&location_addr, (socklen_t)sizeof(location_addr));
    if (0 != uiRet)
    {
        perror("bind");
        exit(1);
    }
    int svErrNo = pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);  

    uiRet = pthread_create(&tid, &attr, (void*)&RecvProc, pThis);
    printf("\r\n %u",uiRet);
    fflush(stdout);

    pstDstPortName->uiType = 0x80000001;
    pstDstPortName->uiInstance = 130987;
    if (0 != dmsGetSockAddr(&TagSockAddr, pstDstPortName))
    {       
        printf("\r\ndmsGetSockAddr Failed 0x%x",uiRet);
        return -1;
    }
//    struct iovec  astIovec[1];
    for (j= 0; ;j++)
    {
        if(j%iNum != 0)
        {
/*            pBuf = malloc(uiSize);
            memset(pBuf, 0, uiSize);*/
            sendto(stSocket, (void*)Buf, uiSize, 0,
                        (struct sockaddr*)&TagSockAddr, sizeof(TagSockAddr));

            /*当前只使用发送一个分片接口*/
            //uiRet = sendto(stSocket, pBuf, uiSize, 0, (__CONST_SOCKADDR_ARG)(struct sockaddr_tipc *)&TagSockAddr, sizeof(TagSockAddr));
            if (0>uiRet)
            {
                perror("sendmsg");
                return 10000;
            }
//            printf("send num is %d",j);
        }
        else
        {
            usleep(4000);
        }
    }
    return 0;
}

 

 

posted @ 2022-05-05 23:22  留一手丶映月  阅读(1269)  评论(0)    收藏  举报