3

想象一个模式:

namespace MyEvents;  

table EventAddress  
{  
  id:uint;  
  timestamp:ulong;  
  adress:string;  
}  

table EventSignalStrength  
{  
  id:uint;  
  timestamp:ulong; 
  strength:float;   
}  

table EventStatus  
{  
  status:string;  
}  

union Events {EventAddress, EventSignalStrength, EventStatus}  

table EventHolder  
{  
  theEvent:Events;  
}  

root_type EventHolder;  

对于状态消息“EXIT”,在 C++ 中我编码并通过电线发送,如:

std::string message("EXIT");  
flatbuffers::FlatBufferBuilder builder;  
auto messageString= builder.CreateString(message);  // Message to send.  
auto statusEvent= MyEvents::CreateEventStatus(builder, messageString);  
auto eventHolder= MyEvents::CreateEventHolder(builder, MyEvents::Events_EventStatus, statusEvent.Union());  
builder.Finish(eventHolder);  

// Code to decode to check my work omitted, but the data decode properly in my real-world application.  

ret= sendto(m_udpSocket, reinterpret_cast<const char*>(builder.GetBufferPointer()), static_cast<int>(builder.GetSize()), 0, reinterpret_cast<SOCKADDR *>(&m_destination), sizeof(m_destination));  

对于相同的消息“EXIT”,我在 C# 中编码并通过网络发送,例如:

string message= "EXIT";  
FlatBufferBuilder builder = new FlatBufferBuilder(1);  
StringOffset messageOffset = builder.CreateString(message);  
EventStatus.StartEventStatus(builder);  
EventStatus.AddStatus(builder, messageOffset);  
Offset<EventStatus> eventStatusOffset = EventStatus.EndEventStatus(builder);  

EventHolder.StartEventHolder(builder);  
EventHolder.AddTheEventType(builder, Events.EventStatus);  
EventHolder.AddTheEvent(builder, eventStatusOffset.Value);  
Offset<EventHolder> eventHolderOffset = EventHolder.EndEventHolder(builder);  

EventHolder.FinishEventHolderBuffer(builder, eventHolderOffset);  

// Test the encoding by decoding:  
EventHolder flatBuffer = EventHolder.GetRootAsEventHolder(builder.DataBuffer);  
Events flatBufferType = flatBuffer.TheEventType;  // Type looks good.  
EventStatus decodedEvent= new EventStatus();  
flatBuffer.GetDataObject<EventStatus>(decodedEvent);  // decodedEvent.Status looks good.  

// This code seems to send the correct data:  
Byte[] sendSized = builder.SizedByteArray();  
udpClient.Send(sendSized, sendSized.Length);  

// This code does not seem to send the correct data:  
//ByteBuffer sendByteBuffer = builder.DataBuffer;  
//udpClient.Send(sendByteBuffer.Data, sendByteBuffer.Data.Length);  

在我用 C# 编写的客户端应用程序中,我解码为:

Byte[] receiveBytes = udpClient.Receive(ref m_remoteEndpoint);  
ByteBuffer flatBufferBytes= new ByteBuffer(receiveBytes);  
EventHolder flatBuffer = EventHolder.GetRootAsEventHolder(flatBufferBytes);  
Events flatBufferType= flatBuffer.DataObjectType;  
EventAddress eventAddress = null;  
EventSignalStrength eventSignalStrength = null;  
EventStatus eventStatus = null;  
switch (flatBufferType)  
{  
  case Events.EventAddress:  
  {  
    eventAddress = new EventAddress();  
    flatBuffer.GetDataObject<EventAddress>(eventAddress);  
    ProcessEventAddress(eventAddress);  
    break;  
  }  

  case Events.EventSignalStrength:  
  {  
    eventSignalStrength = new EventSignalStrength();  
    flatBuffer.GetDataObject<EventSignalStrength>(eventSignalStrength);  
    ProcessEventSignalStrength(eventSignalStrength);  
    break;  
  }  

  case Events.EventStatus:  
  {  
    eventStatus= new EventStatus();  
    flatBuffer.GetDataObject<EventStatus>(eventStatus);  
    Console.WriteLine("\nStatus Message: {0}", eventStatus.status);  
    break;  
  }  
}  
  • 当我收到来自 C++ 应用程序的 EventStatus 消息时,它们会正确解码。
  • 当我从 C# 发送应用程序收到 EventStatus 消息时,它们会正确解码。
  • 当我转储从应用程序发送的缓冲区时,它们是(十进制):

  • C++ - 12 0 0 0 8 0 14 0 7 0 8 0 8 0 0 0 0 0 0 4 12 0 0 0 0 0 6 0 8 0 4 0 6 0 0 0 4 0 0 0 4 0 0 0 69 88 73 84 0 0 0 0

  • C# - 12 0 0 0 8 0 10 0 9 0 4 0 8 0 0 0 12 0 0 0 0 4 6 0 8 0 4 0 6 0 0 0 4 0 0 0 4 0 0 0 69 88 73 84 0 0 0 0

最初,来自 C# 发件人的消息没有正确解码 - 现在可以了。我对发件人进行了更改,所以可能没有重建。

  • 我有点困惑,接收到的 C++ 缓冲区和 C# 缓冲区不同,但它们正确解码为相同的结果。
  • 我的现实世界模式要复杂得多——我是否在 C# 端遵循正确的解码程序?
  • 我是否遵循正确的程序将 flatbuffer 减少到 Byte[] 以便在 C# 中通过线路发送?好像是我,但是好像有一段时间没用了......

任何输入表示赞赏。

4

1 回答 1

0

ByteBuffer 包含缓冲区,但不一定位于偏移量 0,所以是的,将其转换为字节数组(或从其起始偏移量发送 bytebuffer 内容)是发送它的唯一正确方法。

不同语言的编码可能不同,因为实现可能以不同的顺序序列化事物。这里,C++实现决定在偏移量之前写入union类型字段,恰好对齐效率低下,所以稍微大了一点。C# 则相反。

于 2016-06-08T18:25:00.267 回答