我正在尝试为在线云计算课程作业实施 Gossip 风格的会员协议,但遇到了一个奇怪的问题。当成员进入网络时,他们向“介绍人节点”报告,该节点向他们发送网络成员表。为此,分配的第一步是实现 JOINREQ 和 JOINREP 消息。
新节点进来 -> 将 JOINREQ 发送给介绍人。介绍人收到 JOINREQ -> 包含成员资格表的 JOINREP 回复。
我已经实现了这些消息,但似乎有些节点在收到垃圾数据时会在其成员表中随机获取垃圾数据。这是一个例子:
因此,对于所描述的问题,这里是代码
bool MP1Node::recvCallBack(void *env, char *data, int size ) {
MessageHdr *msg;
msg = (MessageHdr*) data;
if(msg->msgType == JOINREQ)
{
long *newMemberHeartBeat = (long*)malloc(sizeof(long));
Address *replyAddr = (Address*)malloc(sizeof(Address));
memcpy(replyAddr, (char *)(msg+1), sizeof(Address));
memcpy(newMemberHeartBeat, (char *)(msg+1) + 1 + sizeof(Address), sizeof(long));
//Add this member to member list
int id = replyAddr->addr[0];
short port = replyAddr->addr[4];
memberNode->memberList.emplace_back(id, port, *newMemberHeartBeat, (long)par->getcurrtime());
// create JOINREP message
size_t msgsize = sizeof(MessageHdr) + sizeof(memberNode->memberList) + sizeof(long) + 1;
msg = (MessageHdr *) malloc(msgsize * sizeof(char));
msg->msgType = JOINREP;
memcpy((char *)(msg+1), &memberNode->memberList, sizeof(memberNode->memberList));
emulNet->ENsend(&memberNode->addr, replyAddr, (char *)msg, msgsize);
//Printing to debuglog
#ifdef DEBUGLOG
string t = "Sending Table to " + replyAddr->getAddress();
log->LOG(&memberNode->addr, t.c_str());
for(auto it = memberNode->memberList.begin(); it != memberNode->memberList.end(); it++)
{
string s = "ID: " + to_string(it->getid()) + " Heartbeat: " + to_string(it->getheartbeat()) + " Timestamp: " + to_string(it->gettimestamp());
log->LOG(&memberNode->addr, s.c_str());
}
log->LOG(&memberNode->addr, "-----------------------");
#endif
free(msg);
free(newMemberHeartBeat);
free(replyAddr);
}
else if(msg->msgType == JOINREP)
{
memcpy(&(memberNode->memberList), (char *)(msg+1), size - sizeof(msg+1));
//Printing to debuglog
#ifdef DEBUGLOG
log->LOG(&memberNode->addr, "Received Table:");
for(auto it = memberNode->memberList.begin(); it != memberNode->memberList.end(); it++)
{
string s = "ID: " + to_string(it->getid()) + " Heartbeat: " + to_string(it->getheartbeat()) + " Timestamp: " + to_string(it->gettimestamp());
log->LOG(&memberNode->addr, s.c_str());
}
log->LOG(&memberNode->addr, "-----------------------");
#endif
}
}
课程讲师在这门课程的论坛上非常不活跃,我不知道该去哪里寻求帮助。这是我的 github 存储库的链接,其中包含更多代码和文件,以及分配规范。Github
我想我想问的主要问题是我构建消息的方式是否有问题,或者这是否是节点故障的结果?这是一个虚拟网络,因此它可能会在这些点发生故障。有关更多信息,报告垃圾值的始终是相同的节点,但每次的值都不同:
1st run
9.0.0.0:0 [4] Received Table:
9.0.0.0:0 [4] ID: 0 Heartbeat: 140736297693200 Timestamp: 1
9.0.0.0:0 [4] ID: 3 Heartbeat: 0 Timestamp: 1
9.0.0.0:0 [4] ID: 4 Heartbeat: 0 Timestamp: 1
9.0.0.0:0 [4] ID: 5 Heartbeat: 0 Timestamp: 2
9.0.0.0:0 [4] ID: 6 Heartbeat: 0 Timestamp: 2
9.0.0.0:0 [4] ID: 7 Heartbeat: 0 Timestamp: 2
9.0.0.0:0 [4] ID: 8 Heartbeat: 0 Timestamp: 2
9.0.0.0:0 [4] ID: 9 Heartbeat: 0 Timestamp: 3
2nd run:
9.0.0.0:0 [4] Received Table:
9.0.0.0:0 [4] ID: 0 Heartbeat: 140736544485392 Timestamp: 1
9.0.0.0:0 [4] ID: 3 Heartbeat: 0 Timestamp: 1
9.0.0.0:0 [4] ID: 4 Heartbeat: 0 Timestamp: 1
9.0.0.0:0 [4] ID: 5 Heartbeat: 0 Timestamp: 2
9.0.0.0:0 [4] ID: 6 Heartbeat: 0 Timestamp: 2
9.0.0.0:0 [4] ID: 7 Heartbeat: 0 Timestamp: 2
9.0.0.0:0 [4] ID: 8 Heartbeat: 0 Timestamp: 2
9.0.0.0:0 [4] ID: 9 Heartbeat: 0 Timestamp: 3
3rd run:
9.0.0.0:0 [4] Received Table:
9.0.0.0:0 [4] ID: 0 Heartbeat: 140736815972368 Timestamp: 1
9.0.0.0:0 [4] ID: 3 Heartbeat: 0 Timestamp: 1
9.0.0.0:0 [4] ID: 4 Heartbeat: 0 Timestamp: 1
9.0.0.0:0 [4] ID: 5 Heartbeat: 0 Timestamp: 2
9.0.0.0:0 [4] ID: 6 Heartbeat: 0 Timestamp: 2
9.0.0.0:0 [4] ID: 7 Heartbeat: 0 Timestamp: 2
9.0.0.0:0 [4] ID: 8 Heartbeat: 0 Timestamp: 2
9.0.0.0:0 [4] ID: 9 Heartbeat: 0 Timestamp: 3