0

Background information for my question:

  1. I have a basic TCP/IP a server-client in c++ language,
  2. I create a lot of structures (for different packages) like this;

     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];
    
  3. I am trying to pass data into structures on server side;

        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();}
    
  4. Pop functions like this;

        int32_t TcpServer::pop32(){
        int32_t ch;
        if(::recv(_sockFd, &ch, 4, 0)>0)
        return getLeValue(ch);   // nhton hnton functions
    

I can't pass the data into structures, anyone have idea for this?

  • 3
    "I can't pass the data into structures" what do you mean exactly? Code doesn't compile? Code doesn't do what you want? – RyanP Mar 13 '17 at 13:39
  • @Someprogrammerdude thanks i edited, but still does not work – Oğuzhan Avcı Mar 13 '17 at 13:45
  • @RyanP Code does not work, I maybe this wrong method while passing the data into structure – Oğuzhan Avcı Mar 13 '17 at 13:48
  • The TCP is like an invisible byte elevator. You send some in at one end, and they come out in the same order at the other end. It is up to you to manage serialization and deserialization of the data. – Colin Mar 13 '17 at 13:51
  • `::recv(_sockFd, &ch, 4, 0)>0` does not imply that four `char`s have been read – it could be less. – molbdnilo Mar 13 '17 at 14:58

1 Answers1

0

You should write your struct into a byte array and then send the byte array. You should never write a struct in a binary way, neither to a file nor to a socket. On the other side you read the byte array and then read back the values into your structure.

Here's some sample code how I do it. Endianess and padding are no problem with this approach. It gives you also better performance to do so than to write every single value to the socket. I'm using this to send UDP datagrams, but it could also be used to send it over TCP.

You need some functions like the following ones.

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;
}

EDIT: I've found the post which was guiding me to the right path some time ago. Here it is with some more explanations: Passing a structure through Sockets in C

Community
  • 1
  • 1
user743414
  • 936
  • 10
  • 23