在opendds的调试日志中大量充斥各种entity的guid,如下所示:
(838182|838209) DataLink::release_reservations() - releasing association local: 0103bab5.84e0eba6.ca269681.01000004(b02bd8da) <--> with remote 0103bab5.84e0eba6.a56d6aff.01000003(453a5921).
如上所示,标红部分所示的就是GUID,刚开始看到也是很头疼,经过分析源码终于搞明白了这个GUID的含义下面进行详细的介绍。
首先需要搞清楚的是就是GUID一共有16个字节,其中前12个字节的含义是GUID的前缀;后4个字节表示的是entity的类型和id。具体含义如下图所示:
上面的图非常清晰的将各个字节的含义介绍清楚了。文字介绍如下所示:
- 前2个字节表示的厂商,目前代码中固定是0103
- 从第3个字节开始的6个字节是网卡的mac地址
- 从第9个字节开始的2个字节是应用程序进程pid的低16位(2个字节)
- 从第11个字节的2个字节的一个随机数,目前我也不太理解这个随机数的意义,仅知道这个是随机数,有知道的可以给我留言告诉我,感激不尽
- 从第13个字节开始的3个字节标识的本地entity(实体)的id,这个id从1开始,依次递增。
- 第16个字节的函数含义是entity(实体)类型
entity类型的枚举定义如下所示:
enum EntityKind {
KIND_UNKNOWN, ///< ENTITYKIND_USER_UNKNOWN and ENTITYKIND_BUILTIN_UNKNOWN
KIND_PARTICIPANT, ///< ENTITYKIND_BUILTIN_PARTICIPANT
KIND_USER_WRITER, ///< ENTITYKIND_USER_WRITER_WITH_KEY and ENTITYKIND_USER_WRITER_NO_KEY
KIND_USER_READER, ///< ENTITYKIND_USER_READER_WITH_KEY and ENTITYKIND_USER_READER_NO_KEY
KIND_USER_TOPIC, ///< ENTITYKIND_OPENDDS_TOPIC
KIND_BUILTIN_WRITER, ///< ENTITYKIND_BUILTIN_WRITER_WITH_KEY and ENTITYKIND_USER_WRITER_NO_KEY
KIND_BUILTIN_READER, ///< ENTITYKIND_BUILTIN_READER_WITH_KEY and ENTITYKIND_USER_READER_NO_KEY
KIND_BUILTIN_TOPIC, ///< ENTITYKIND_BUILTIN_TOPIC
KIND_PUBLISHER, ///< Publisher (OpenDDS-specific)
KIND_SUBSCRIBER, ///< Subscriber (OpenDDS-specific)
KIND_USER ///< For creating custom GUIDs for things that are not DDS entities (OpenDDS-specific)
};
guid赋值函数源码如下所示:
void
GuidGenerator::populate(DCPS::GUID_t &container)
{
container.guidPrefix[0] = DCPS::VENDORID_OCI[0];
container.guidPrefix[1] = DCPS::VENDORID_OCI[1];
const ACE_UINT16 count = getCount();
ACE_OS::memcpy(&container.guidPrefix[2], node_id_, NODE_ID_SIZE);
container.guidPrefix[8] = static_cast<CORBA::Octet>(pid_ >> 8);
container.guidPrefix[9] = static_cast<CORBA::Octet>(pid_ & 0xFF);
container.guidPrefix[10] = static_cast<CORBA::Octet>(count >> 8);
container.guidPrefix[11] = static_cast<CORBA::Octet>(count & 0xFF);
}
opendds 随机数生成源码实现:
ACE_UINT16
GuidGenerator::getCount(bool doIncrement)
{
ACE_Guard<ACE_Thread_Mutex> guard(counter_lock_);
if (doIncrement) {
++counter_;
}
return counter_;
}
GuidGenerator::GuidGenerator()
: pid_(ACE_OS::getpid())
{
unsigned seed = static_cast<unsigned>(SystemTimePoint::now().value().usec() + reinterpret_cast<size_t>(this));
if (pid_ == -1) {
pid_ = static_cast<pid_t>(ACE_OS::rand_r(&seed));
}
#ifdef ACE_HAS_CPP11
std::mt19937 generator(seed);
std::uniform_int_distribution<ACE_UINT16> distribution(0, ACE_UINT16_MAX);
counter_ = distribution(generator);
#else
counter_ = static_cast<ACE_UINT16>(ACE_OS::rand_r(&seed));
#endif
ACE_OS::macaddr_node_t macaddress;
const int result = ACE_OS::getmacaddress(&macaddress);
#ifndef ACE_HAS_IOS
if (-1 != result) {
ACE_OS::memcpy(node_id_, macaddress.node, NODE_ID_SIZE);
} else {
for (int i = 0; i < NODE_ID_SIZE; ++i) {
node_id_[i] = static_cast<unsigned char>(ACE_OS::rand_r(&seed));
}
}
#else
// iOS has non-unique MAC addresses
ACE_UNUSED_ARG(result);
for (int i = 0; i < NODE_ID_SIZE; ++i) {
node_id_[i] = static_cast<unsigned char>(ACE_OS::rand_r(&seed));
}
#endif /* ACE_HAS_IOS */
}