wangzhengquan
2021-01-25 14be935a4f8231233487d510c8db0b544bcf0f69
README.md
@@ -1,121 +1,293 @@
<<<<<<< HEAD
## 实例
# 1. 实例
以下实例代码在`demo`文件夹下
## 1.1 Bus模式
**Source**
`dgram_mod_bus.c`
**编译**
安装好so包后,用如下的方式编译,shm_queue是通信队列包,usgcommon是公共包,pthread是系统的线程包
`g++ dgram_mod_bus.c -mcx16 -std=c++11 -lshm_queue -lusgcommon -lpthread`
**演示**
启动bus `./dgram_mod_bus server 8`。然后打开两个客户端连接bus, 第一个客户端订阅 "news", 第二个客户端发布 "news". 第一个客户端会收到第二个客户端推送的信息。
启动bus
```
$  ./dgram_mod_bus server 8
```
第一个客户端订阅 "news"
```
$ ./dgram_mod_bus client 8
Can I help you? sub, pub or quit
sub
Please input topic!
news
Sub success!
Can I help you? sub, pub or quit
收到订阅消息:111111111111111111111
 ```
第二个客户端发布 "news"
 ```
$  ./dgram_mod_bus client 8
Can I help you? sub, pub or quit
pub
Please input topic and content
news 111111111111111111111
Pub success!
Can I help you? sub, pub or quit
 ```
这里可以打开许多个客户端发布和订阅消息。
## 1.2 req_rep模式, 适应于注册
**Source** `dgram_mod_req_rep.c`
**编译** 同上
**演示**
```
#include "shm_queue_wrapper.h"
#include "mm.h"
## 启动注册中心
./dgram_mod_req_rep server 2 & node0=$! && sleep 1
## 向注册中心发送消息
./dgram_mod_req_rep client 2 node1
kill $node0
```
typedef struct message_t
{
   char method[20];
   int code;
} message_t;
## survey模式, 适应于心跳
**Source** `dgram_mod_survey.c`
void test1() {
   unsigned int i = 0;
   int key = 2;
    //
   size_t qsize = 16;
   void * queue = shmqueue_init( key, qsize, sizeof(message_t));
   message_t item;
   // LockFreeQueue<struct Item> queue(16);
   for(i = 0; i < qsize; i++) {
      sprintf(item.method, "hello");
      item.code = i ;
      if(shmqueue_push(queue, (void *)&item)) {
           printf("push:%d %s\n", item.code, item.method );
      }
   }
   struct timespec timeout = {1, 0};
**编译** 同上
   i = 0;
   while((shmqueue_pop_timeout(queue, (void *)&item, &timeout)) ) {
       printf("pop:%d %s\n", item.code, item.method );
      // cout <<  item.pic << endl;
       i++;
   }
**演示**
启动心跳中心
```
$ ./dgram_mod_survey server 3
   //销毁队列
   shmqueue_destroy(queue);
}
RECEIVED HREARTBEAT FROM 1000: 0
RECEIVED HREARTBEAT FROM 1000: 1
RECEIVED HREARTBEAT FROM 1000: 2
RECEIVED HREARTBEAT FROM 1000: 3
RECEIVED HREARTBEAT FROM 1000: 4
RECEIVED HREARTBEAT FROM 1000: 5
RECEIVED HREARTBEAT FROM 1000: 6
RECEIVED HREARTBEAT FROM 1000: 7
RECEIVED HREARTBEAT FROM 1000: 8
RECEIVED HREARTBEAT FROM 1000: 9
```
打开一个客户端,连接心跳中心
```
$ ./dgram_mod_survey client 3
SEND HEART:0
SEND HEART:1
SEND HEART:2
SEND HEART:3
SEND HEART:4
SEND HEART:5
SEND HEART:6
SEND HEART:7
SEND HEART:8
SEND HEART:9
```
# 1.3 网络测试
在三个节点上node1 node2 node3 分别执行下面的程序
```
# 打开请求应答的server
./dgram_mod_req_rep server 11 &
# 开启bus
./dgram_mod_bus server 8 &
# 开启网络server
./net_mod_socket server 5000 &
# 订阅bus
./dgram_mod_bus client 8
```
在其中一个节点执行网络客户端程序,向其他三个节点发送消息
```
./net_mod_socket client 5000
```
# 2. 接口说明
shm_mm_wraper.h
```
/**
 * 初始化共享内存
 * @size 共享内存大小, 单位M
 *
 */
void shm_mm_wrapper_init(int size);
/**
 * 销毁共享内存
 * 整个进程退出时需要执行这个方法,该方法首先会检查是否还有其他进程在使用该共享内存,如果还有其他进程在使用就只是detach,如果没有其他进程在使用则销毁整块内存。
 */
void shm_mm_wrapper_destroy();
```
dgram_mod_socket.h
```
/**
 * 创建socket
 * @return socket地址
*/
void *dgram_mod_open_socket();
/**
 * 关闭socket
 * @return 0 成功, 其他值 失败的错误码
*/
int dgram_mod_close_socket(void * _socket);
/**
 * 绑定端口到socket, 如果不绑定则系统自动分配一个
 * @return 0 成功, 其他值 失败的错误码
*/
int dgram_mod_bind(void * _socket, int port);
/**
 * 发送信息
 * @port 发送给谁
 * @return 0 成功, 其他值 失败的错误码
 */
int dgram_mod_sendto(void *_socket, const void *buf, const int size, const int port);
/**
 * 接收信息
 * @port 从谁哪里收到的信息
 * @return 0 成功, 其他值 失败的错误码
*/
int dgram_mod_recvfrom(void *_socket, void **buf, int *size, int *port);
/**
 * 发送请求信息并等待接收应答
 * @port 发送给谁
 * @return 0 成功, 其他值 失败的错误码
*/
int dgram_mod_sendandrecv(void * _socket, const void *send_buf, const int send_size, const int port, void **recv_buf, int *recv_size) ;
/**
 * 启动bus
 *
 * @return 0 成功, 其他值 失败的错误码
*/
int  dgram_mod_start_bus(void * _socket);
/**
 * 订阅指定主题
 * @topic 主题
 * @size 主题长度
 * @port 总线端口
 */
int  dgram_mod_sub(void * _socket, void *topic, int size, int port);
/**
 * 发布主题
 * @topic 主题
 * @content 主题内容
 * @port 总线端口
 */
int  dgram_mod_pub(void * _socket, void *topic, int topic_size, void *content, int content_size, int port);
/**
 * 获取soket端口号
 */
int dgram_mod_get_port(void * _socket) ;
/**
 * 释放存储接收信息的buf
 */
void dgram_mod_free(void *buf) ;
```
net_mod_server_socket_wrapper.h
```
/**
 * 创建
 */
void *net_mod_server_socket_open(int port) ;
/**
 * 关闭
 */
void net_mod_server_socket_close(void *_sockt) ;
/**
 * 启动
 */
void net_mod_server_socket_start(void *_sockt);
```
net_mod_socket_wrapper.h
```
/**
 * 创建
 */
void * net_mod_socket_open();
/**
 * 关闭
 */
void net_mod_socket_close(void *_sockt);
/**
 * 向node_arr 中的所有网络节点发送请求消息,节点的返回信息汇总并存储在recv_arr中
 * @node_arr 网络节点组, @node_arr_len该数组长度
 * @send_buf 发送的消息,@send_size 该消息体的长度
 * @recv_arr 返回的应答消息组,@recv_arr_size 该数组长度
 * @return 成功发送的节点的个数
 */
int net_mod_socket_sendandrecv(void *_sockt, net_node_t *node_arr, int node_arr_len, void *send_buf, int send_size,
   net_mod_recv_msg_t ** recv_arr, int *recv_arr_size);
/**
 * 销毁sendandrecv方法返回的消息组
 * @arr 消息组
 * @size 消息组的长度
 */
void  net_mod_socket_free_recv_msg_arr(net_mod_recv_msg_t * arr, int size);
 /**
 * 向node_arr 中的所有网络节点发布消息
 * @node_arr 网络节点组, @node_arr_len该数组长度
 * @topic 主题,@topic_size 该主题的长度
 * @content 内容,@content_size 内容长度
 * @return 成功发布的节点的个数
 */
int net_mod_socket_pub(void *_sockt, net_node_t *node_arr, int node_arr_len, char *topic, int topic_size, void *content, int content_size);
```
 
int main () {
   test1();
   //整个进程退出时需要执行这个方法,该方法首先会检查是否还有其他进程在使用该共享内存,如果还有其他进程在使用就只是detach,如果没有其他进程在使用则销毁整块内存。
   mm_destroy();
   return 0;
}
```
## 接口说明
```
/**
 * 初始化
 * @ shmqueue
 * @ key 标识共享队列的唯一key
 * @ queue_size 队列大小 , 这个值必须是2的指数即 1, 2, 4, 8, 16 等
 * @ ele_size 队列中元素大小, 这个值不能超过512,当然如果需要可以调整这个最大限制
 */
void* shmqueue_init(int key, int queue_size, int ele_size);
/**
 * 销毁
*/
void shmqueue_destroy(void *shmqueue);
/**
 * 队列元素的个数
 */
uint32_t shmqueue_size(void *shmqueue);
/**
 * 是否已满
 */
int shmqueue_full(void *shmqueue);
/**
 * 是否为空
 */
int shmqueue_empty(void *shmqueue);
/**
 * 入队, 队列满时等待
 */
int shmqueue_push(void *shmqueue, void *src_ele);
/**
 * 入队, 队列满时立即返回
 */
int shmqueue_push_nowait(void *shmqueue, void *src_ele);
/**
 * 入队, 指定时间内入队不成功就返回
 */
int shmqueue_push_timeout(void *shmqueue, void *src_ele, struct timespec * timeout);
/**
 * 出队, 队列空时等待
 */
int shmqueue_pop(void *shmqueue, void *dest_ele);
/**
 * 出队, 队列空时立即返回
 */
int shmqueue_pop_nowait(void *shmqueue, void *dest_ele);
/**
 * 出队, 指定时间内出队不成功就返回
 */
int shmqueue_pop_timeout(void *shmqueue, void *dest_ele, struct timespec * timeout);
```
=======
## softbus
shm的通讯库
>>>>>>> dd08a8134dea74ac30213c1b8580bff34ee7095b