gossip(流言蜚语)协议的实现代码和运行demo

代码的下载地址为:点击这里

安装过程:

git clone https://github.com/izeigerman/pittacus.git
cd pittacus
mkdir build && cd build
cmake ..
make
sudo make install
sudo ldconfig

demo的代码如下:

demo_node代码:

#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <poll.h>
#include <time.h>
#include "gossip.h"
#include "config.h"

const char DATA_MESSAGE[] = "Hello World";

void data_receiver(void *context, pittacus_gossip_t *gossip, const uint8_t *data, size_t data_size) {
    // This function is invoked every time when a new data arrives.
    printf("Data arrived: %s\n", data);
}

int main(int argc, char **argv) {
    char *node_id = "0";
    if (argc > 1) {
        node_id = argv[1];
    }
    char message_with_ts[256];
    size_t message_with_ts_size = 0;
    char message[256];
    sprintf(message, "[%s]: %s", node_id, DATA_MESSAGE);

    struct sockaddr_in self_in;
    self_in.sin_family = AF_INET;
    self_in.sin_port = 0; // pick up a random port.
    inet_aton("127.0.0.1", &self_in.sin_addr);

    // Filling in the address of the current node.
    pittacus_addr_t self_addr = {
        .addr = (const pt_sockaddr *) &self_in,
        .addr_len = sizeof(struct sockaddr_in)
    };

    // Create a new Pittacus descriptor instance.
    pittacus_gossip_t *gossip = pittacus_gossip_create(&self_addr, &data_receiver, NULL);
    if (gossip == NULL) {
        fprintf(stderr, "Gossip initialization failed: %s\n", strerror(errno));
        return -1;
    }

    // Connect to the active seed node.
    struct sockaddr_in seed_node_in;
    seed_node_in.sin_family = AF_INET;
    seed_node_in.sin_port = htons(65000);
    inet_aton("127.0.0.1", &seed_node_in.sin_addr);

    pittacus_addr_t seed_node_addr = {
        .addr = (const pt_sockaddr *) &seed_node_in,
        .addr_len = sizeof(struct sockaddr_in)
    };

    int join_result = pittacus_gossip_join(gossip, &seed_node_addr, 1);
    if (join_result < 0) {
        fprintf(stderr, "Gossip join failed: %d\n", join_result);
        pittacus_gossip_destroy(gossip);
        return -1;
    }

    // Force Pittacus to send a Hello message.
    if (pittacus_gossip_process_send(gossip) < 0) {
        fprintf(stderr, "Failed to send hello message to a cluster.\n");
        pittacus_gossip_destroy(gossip);
        return -1;
    }

    // Retrieve the socket descriptor.
    pt_socket_fd gossip_fd = pittacus_gossip_socket_fd(gossip);
    struct pollfd gossip_poll_fd = {
        .fd = gossip_fd,
        .events = POLLIN,
        .revents = 0
    };

    int poll_interval = GOSSIP_TICK_INTERVAL;
    int recv_result = 0;
    int send_result = 0;
    int poll_result = 0;
    int send_data_interval = 5; // send data every 5 seconds
    time_t previous_data_msg_ts = time(NULL);
    while (1) {
        gossip_poll_fd.revents = 0;

        poll_result = poll(&gossip_poll_fd, 1, poll_interval);
        if (poll_result > 0) {
            if (gossip_poll_fd.revents & POLLERR) {
                fprintf(stderr, "Gossip socket failure: %s\n", strerror(errno));
                pittacus_gossip_destroy(gossip);
                return -1;
            } else if (gossip_poll_fd.revents & POLLIN) {
                // Tell Pittacus to read a message from the socket.
                recv_result = pittacus_gossip_process_receive(gossip);
                if (recv_result < 0) {
                    fprintf(stderr, "Gossip receive failed: %d\n", recv_result);
                    pittacus_gossip_destroy(gossip);
                    return -1;
                }
            }
        } else if (poll_result < 0) {
            fprintf(stderr, "Poll failed: %s\n", strerror(errno));
            pittacus_gossip_destroy(gossip);
            return -1;
        }
        // Try to trigger the Gossip tick event and recalculate
        // the poll interval.
        poll_interval = pittacus_gossip_tick(gossip);
        if (poll_interval < 0) {
            fprintf(stderr, "Gossip tick failed: %d\n", poll_interval);
            return -1;
        }
        // Send some data periodically.
        time_t current_time = time(NULL);
        if (previous_data_msg_ts + send_data_interval <= current_time) {
            previous_data_msg_ts = current_time;
            message_with_ts_size = sprintf(message_with_ts, "%s (ts = %ld)", message, current_time) + 1;
            pittacus_gossip_send_data(gossip, (const uint8_t *) message_with_ts, message_with_ts_size);
        }
        // Tell Pittacus to write existing messages to the socket.
        send_result = pittacus_gossip_process_send(gossip);
        if (send_result < 0) {
            fprintf(stderr, "Gossip send failed: %d, %s\n", send_result, strerror(errno));
            pittacus_gossip_destroy(gossip);
            return -1;
        }
    }
    pittacus_gossip_destroy(gossip);

    return 0;
}

demo_send_node代码如下:

#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <poll.h>
#include <time.h>
#include "gossip.h"
#include "config.h"

const char DATA_MESSAGE[] = "Hi there";

void data_receiver(void *context, pittacus_gossip_t *gossip, const uint8_t *data, size_t data_size) {
    // This function is invoked every time when a new data arrives.
    printf("Data arrived: %s\n", data);
}

int main(int argc, char **argv) {
    struct sockaddr_in self_in;
    self_in.sin_family = AF_INET;
    self_in.sin_port = htons(65000);
    inet_aton("127.0.0.1", &self_in.sin_addr);

    // Filling in the address of the current node.
    pittacus_addr_t self_addr = {
        .addr = (const pt_sockaddr *) &self_in,
        .addr_len = sizeof(struct sockaddr_in)
    };

    // Create a new Pittacus descriptor instance.
    pittacus_gossip_t *gossip = pittacus_gossip_create(&self_addr, &data_receiver, NULL);
    if (gossip == NULL) {
        fprintf(stderr, "Gossip initialization failed: %s\n", strerror(errno));
        return -1;
    }

    // No seed nodes are provided.
    int join_result = pittacus_gossip_join(gossip, NULL, 0);
    if (join_result < 0) {
        fprintf(stderr, "Gossip join failed: %d\n", join_result);
        pittacus_gossip_destroy(gossip);
        return -1;
    }

    // Retrieve the socket descriptor.
    pt_socket_fd gossip_fd = pittacus_gossip_socket_fd(gossip);
    struct pollfd gossip_poll_fd = {
        .fd = gossip_fd,
        .events = POLLIN,
        .revents = 0
    };

    int poll_interval = GOSSIP_TICK_INTERVAL;
    int recv_result = 0;
    int send_result = 0;
    int poll_result = 0;
    while (1) {
        gossip_poll_fd.revents = 0;

        poll_result = poll(&gossip_poll_fd, 1, poll_interval);
        if (poll_result > 0) {
            if (gossip_poll_fd.revents & POLLERR) {
                fprintf(stderr, "Gossip socket failure: %s\n", strerror(errno));
                pittacus_gossip_destroy(gossip);
                return -1;
            } else if (gossip_poll_fd.revents & POLLIN) {
                // Tell Pittacus to read a message from the socket.
                recv_result = pittacus_gossip_process_receive(gossip);
                if (recv_result < 0) {
                    fprintf(stderr, "Gossip receive failed: %d\n", recv_result);
                    pittacus_gossip_destroy(gossip);
                    return -1;
                }
            }
        } else if (poll_result < 0) {
            fprintf(stderr, "Poll failed: %s\n", strerror(errno));
            pittacus_gossip_destroy(gossip);
            return -1;
        }
        // Try to trigger the Gossip tick event and recalculate
        // the poll interval.
        poll_interval = pittacus_gossip_tick(gossip);
        if (poll_interval < 0) {
            fprintf(stderr, "Gossip tick failed: %d\n", poll_interval);
            return -1;
        }
        // Tell Pittacus to write existing messages to the socket.
        send_result = pittacus_gossip_process_send(gossip);
        if (send_result < 0) {
            fprintf(stderr, "Gossip send failed: %d, %s\n", send_result, strerror(errno));
            pittacus_gossip_destroy(gossip);
            return -1;
        }
    }
    pittacus_gossip_destroy(gossip);

    return 0;
}

运行时注意加上include的包:

运行代码:

gcc -I include的绝对路径 demo_node.c -o demonode -lpittacus
gcc -I include的绝对路径 demo_send_node.c -o demosend -lpittacus

执行阶段:

./demonode
./demosend

可能遇到的问题error while loading shared libraries :libpittacus.so:cannot open shared object file:No such file or directory

解决方法如下:vim etc/ld.so.conf

将pittacus.so地址放入到conf中。

pattacus.so的地址是在安装的时候会出现(可以在进行安装查看或者find 包名)

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值