TIPC
参考
- https://blog.csdn.net/weixin_33630090/article/details/116927658
- https://www.csdn.net/tags/MtTaAg5sNTY5NTIzLWJsb2cO0O0O.html
简介
简介
- 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; }

浙公网安备 33010602011771号