传递数据结构
Passing data structures
我的问题的背景信息:
- 我有一个基本的 TCP/IP c++ 语言的服务器客户端,
我创建了很多这样的结构(针对不同的包);
struct PACKED AddOrderMessageNoMPIDPackage
int8_t code //code of package 'A'
int32_t nanosecond_elapsed;
int64_t order_id;
int32_t order_book_id;
char side;
int32_t order_book_position;
char session[10];
我正在尝试将数据传递到服务器端的结构中;
A.to_little_endian(); //(Firstly i use `nhton,hnton` fucntions)
A.code = server.pop(); //Server is a class include pop functions etc
A.nanosecond_elapsed = server.pop32();
A.order_book_id = server.pop32();
for (int i = 0; i < 32; i++) {
A.symbol[i] = server.pop();}
弹出函数是这样的;
int32_t TcpServer::pop32(){
int32_t ch;
if(::recv(_sockFd, &ch, 4, 0)>0)
return getLeValue(ch); // nhton hnton functions
我无法将数据传递到结构中,有人对此有想法吗?
您应该将结构写入字节数组,然后发送字节数组。您永远不应该以二进制方式编写结构,无论是文件还是套接字。
另一方面,您读取字节数组,然后将值读回到您的结构中。
下面是一些示例代码,我是如何做到的。 Endianess 和 padding 对这种方法没有问题。与将每个值写入套接字相比,它还为您提供了更好的性能。
我用它来发送 UDP 数据报,但它也可以用于通过 TCP 发送它。
您需要如下功能。
virtual MESSAGE_BUFFER * GetMessageAsBinaryPtr()
{
MESSAGE_BUFFER * binaryMsg = new MESSAGE_BUFFER;
UINT8 * ptrBuffer = &(*binaryMsg)[0];
ptrBuffer = this->serializeUInt16(ptrBuffer, this->m_majorVersion);
ptrBuffer = this->serializeUInt16(ptrBuffer, this->m_minorVersion);
ptrBuffer = this->serializeUInt32(ptrBuffer, (UINT32)this->m_messageType);
ptrBuffer = this->serializeUInt64(ptrBuffer, this->m_packetID);
ptrBuffer = this->serializeDouble(ptrBuffer, this->m_timestamp);
return binaryMsg;
}
virtual void CreateFromBinary(MESSAGE_BUFFER buffer)
{
UINT8 * ptrBuffer = &buffer[0];
ptrBuffer = this->deserializeUInt16FromBuffer(ptrBuffer, &this->m_majorVersion);
ptrBuffer = this->deserializeUInt16FromBuffer(ptrBuffer, &this->m_minorVersion);
UINT32 messageType = 0;
ptrBuffer = this->deserializeUInt32FromBuffer(ptrBuffer, &messageType);
this->SetMessageType((MessageTypes)messageType);
ptrBuffer = this->deserializeUInt64FromBuffer(ptrBuffer, &this->m_packetID);
ptrBuffer = this->deserializeDoubleFromBuffer(ptrBuffer, &this->m_timestamp);
}
inline UINT8 * serializeUInt16(UINT8 * buffer, UINT16 value)
{
buffer[1] = value;
buffer[0] = value >> 8;
return buffer + 2;
}
inline UINT8 * deserializeUInt16FromBuffer(UINT8 * buffer, UINT16 * pOutput)
{
*pOutput = (*pOutput << 8) + buffer[0];
*pOutput = (*pOutput << 8) + buffer[1];
return buffer + 2;
}
编辑:
我发现 post 前段时间引导我走上了正确的道路。
这里有一些更多的解释:
Passing a structure through Sockets in C
我的问题的背景信息:
- 我有一个基本的 TCP/IP c++ 语言的服务器客户端,
我创建了很多这样的结构(针对不同的包);
struct PACKED AddOrderMessageNoMPIDPackage int8_t code //code of package 'A' int32_t nanosecond_elapsed; int64_t order_id; int32_t order_book_id; char side; int32_t order_book_position; char session[10];
我正在尝试将数据传递到服务器端的结构中;
A.to_little_endian(); //(Firstly i use `nhton,hnton` fucntions) A.code = server.pop(); //Server is a class include pop functions etc A.nanosecond_elapsed = server.pop32(); A.order_book_id = server.pop32(); for (int i = 0; i < 32; i++) { A.symbol[i] = server.pop();}
弹出函数是这样的;
int32_t TcpServer::pop32(){ int32_t ch; if(::recv(_sockFd, &ch, 4, 0)>0) return getLeValue(ch); // nhton hnton functions
我无法将数据传递到结构中,有人对此有想法吗?
您应该将结构写入字节数组,然后发送字节数组。您永远不应该以二进制方式编写结构,无论是文件还是套接字。 另一方面,您读取字节数组,然后将值读回到您的结构中。
下面是一些示例代码,我是如何做到的。 Endianess 和 padding 对这种方法没有问题。与将每个值写入套接字相比,它还为您提供了更好的性能。 我用它来发送 UDP 数据报,但它也可以用于通过 TCP 发送它。
您需要如下功能。
virtual MESSAGE_BUFFER * GetMessageAsBinaryPtr()
{
MESSAGE_BUFFER * binaryMsg = new MESSAGE_BUFFER;
UINT8 * ptrBuffer = &(*binaryMsg)[0];
ptrBuffer = this->serializeUInt16(ptrBuffer, this->m_majorVersion);
ptrBuffer = this->serializeUInt16(ptrBuffer, this->m_minorVersion);
ptrBuffer = this->serializeUInt32(ptrBuffer, (UINT32)this->m_messageType);
ptrBuffer = this->serializeUInt64(ptrBuffer, this->m_packetID);
ptrBuffer = this->serializeDouble(ptrBuffer, this->m_timestamp);
return binaryMsg;
}
virtual void CreateFromBinary(MESSAGE_BUFFER buffer)
{
UINT8 * ptrBuffer = &buffer[0];
ptrBuffer = this->deserializeUInt16FromBuffer(ptrBuffer, &this->m_majorVersion);
ptrBuffer = this->deserializeUInt16FromBuffer(ptrBuffer, &this->m_minorVersion);
UINT32 messageType = 0;
ptrBuffer = this->deserializeUInt32FromBuffer(ptrBuffer, &messageType);
this->SetMessageType((MessageTypes)messageType);
ptrBuffer = this->deserializeUInt64FromBuffer(ptrBuffer, &this->m_packetID);
ptrBuffer = this->deserializeDoubleFromBuffer(ptrBuffer, &this->m_timestamp);
}
inline UINT8 * serializeUInt16(UINT8 * buffer, UINT16 value)
{
buffer[1] = value;
buffer[0] = value >> 8;
return buffer + 2;
}
inline UINT8 * deserializeUInt16FromBuffer(UINT8 * buffer, UINT16 * pOutput)
{
*pOutput = (*pOutput << 8) + buffer[0];
*pOutput = (*pOutput << 8) + buffer[1];
return buffer + 2;
}
编辑: 我发现 post 前段时间引导我走上了正确的道路。 这里有一些更多的解释: Passing a structure through Sockets in C