Results 1 to 20 of 20

Thread: TCP Write Raw data

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Jan 2006
    Location
    Sta. Eugènia de Berga (Vic - Barcelona - Spain)
    Posts
    869
    Thanks
    70
    Thanked 59 Times in 57 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default TCP Write Raw data

    Hi,

    I'm trying to write raw data thorugh TCPSocket. I have a struct like (Modbus protocol):
    Qt Code:
    1. //Modbus header
    2. typedef struct MB_Request
    3. {
    4. uchar function_code;
    5. quint16 start_adr;
    6. quint16 quantity_regs;
    7. };
    8.  
    9. //Modbus/TCP header, containing the Modbus header
    10. typedef struct MBAP_Header
    11. {
    12. quint16 transaction_id;
    13. quint16 protocol_id;
    14. quint16 len;
    15. uchar unit_id;
    16. };
    17.  
    18. typedef struct MB_Message
    19. {
    20. MBAP_Header mb_hdr;
    21. MB_Request mb_req;
    22. };
    To copy to clipboard, switch view to plain text mode 

    What I don't know is how to send a variable (MB_Message type) as raw data. The documentation show that the data have to be stored as "char *". How have I to do this?

    Thanks,
    Òscar Llarch i Galán

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: TCP Write Raw data

    You can cast a pointer to the structure to char *, but beware that these structures are aligned and for example size of MB_Request is more than 5 bytes. If you use GCC you can add __attribute__((packed)) to pack them. Also make sure that integers have proper endianness.

  3. #3
    Join Date
    Jan 2006
    Location
    Sta. Eugènia de Berga (Vic - Barcelona - Spain)
    Posts
    869
    Thanks
    70
    Thanked 59 Times in 57 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: TCP Write Raw data

    Hi,

    You can cast a pointer to the structure to char *
    Qt Code:
    1. const char* data = (char*)&message;
    2. int ilen = strlen(data);
    3. tcpSocket->write(data,ilen);
    To copy to clipboard, switch view to plain text mode 

    Using this I only recive 1 byte.
    Maybe have I to create a "char*" containing the same values of the struct?

    Thanks,
    Òscar Llarch i Galán

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: TCP Write Raw data

    strlen() is for zero-terminated strings, not for data --- use sizeof message instead.

  5. #5
    Join Date
    Jan 2006
    Location
    Sta. Eugènia de Berga (Vic - Barcelona - Spain)
    Posts
    869
    Thanks
    70
    Thanked 59 Times in 57 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: TCP Write Raw data

    Hi,

    Ok, it seems to work now.
    When the reciver gets the raw data, I have to cast the data to a struct pointer. Right?

    The other question is:
    but beware that these structures are aligned and for example size of MB_Request is more than 5 bytes.
    Also make sure that integers have proper endianness
    What do you mean with that the structures are aligned? And how can I maintain the proper endianess, I think that I'm sending the data as big endian.

    Thanks,
    Òscar Llarch i Galán

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: TCP Write Raw data

    Quote Originally Posted by ^NyAw^ View Post
    What do you mean with that the structures are aligned?
    Check what sizeof( MB_Request ) returns. It contains only 5 bytes of data, yet it's bigger because of performance reasons (i.e. it contains holes between fields). Most likely the protocol expects packed data, so you have to tell your compiler to treat those structures differently.

    http://en.wikipedia.org/wiki/Data_structure_alignment

    Quote Originally Posted by ^NyAw^ View Post
    And how can I maintain the proper endianess, I think that I'm sending the data as big endian.
    QSysInfo::ByteOrder will tell you whether you are using big-endian or little-endian system and you have to convert values to endianness required by the protocol.

  7. #7
    Join Date
    Jan 2006
    Location
    Sta. Eugènia de Berga (Vic - Barcelona - Spain)
    Posts
    869
    Thanks
    70
    Thanked 59 Times in 57 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: TCP Write Raw data

    Hi,

    Check what sizeof( MB_Request ) returns. It contains only 5 bytes of data
    It returns me "14". The structs are 7 bytes(Modbus/TCP header) + 5 bytes (Modbus header) that sum 12. So I think that the struct "MB_Message" contains 1 byte for the first struct and another byte for the second struct.

    Thanks,
    Òscar Llarch i Galán

  8. #8
    Join Date
    Jan 2006
    Location
    Sta. Eugènia de Berga (Vic - Barcelona - Spain)
    Posts
    869
    Thanks
    70
    Thanked 59 Times in 57 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: TCP Write Raw data

    Hi,

    Ok, thanks for the link of "Data structure alignment".

    So, the "Modbus/TCP header" is 7 bytes. The "Modbus header" is 5 bytes. A total of 12 bytes that are 12*8 = 96 bits that are 32 bit aligned.
    So, why "sizeof(MB_Message)" is returning me 14 bytes?

    Thanks,
    Òscar Llarch i Galán

  9. #9
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: TCP Write Raw data

    Quote Originally Posted by ^NyAw^ View Post
    So, why "sizeof(MB_Message)" is returning me 14 bytes?
    Because there are one-byte holes after unit_id and function_code fields.

    I've attached a small application. It prints the addresses of all fields, so you can see how they're placed in the memory. If you use GCC, you can uncomment the #define in line 7 and comment out the one in line 6 to see how unaligned (a.k.a. packed) structures look like.
    Attached Files Attached Files

  10. The following user says thank you to jacek for this useful post:

    ^NyAw^ (23rd November 2007)

  11. #10
    Join Date
    Jan 2006
    Location
    Sta. Eugènia de Berga (Vic - Barcelona - Spain)
    Posts
    869
    Thanks
    70
    Thanked 59 Times in 57 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: TCP Write Raw data

    Hi,

    Ok, so every struct have to be 32-bit aligned.

    Thanks,
    Òscar Llarch i Galán

  12. #11
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: TCP Write Raw data

    Quote Originally Posted by ^NyAw^ View Post
    Ok, so every struct have to be 32-bit aligned.
    Yes, but only in memory on 32-bit (and pseudo-64bit) machines. Other machines might have different alignment. Also usually you don't align data in files* or in network communication.

    * Unless the file format was designed for fast access.

Similar Threads

  1. Replies: 4
    Last Post: 19th October 2007, 19:47
  2. Data model
    By steg90 in forum Qt Programming
    Replies: 3
    Last Post: 17th September 2007, 12:14
  3. FSWriteFork in MAC OS to write data to a file.
    By vishal.chauhan in forum General Programming
    Replies: 5
    Last Post: 2nd July 2007, 06:48
  4. speed of setdata - lots of items in treeview
    By Big Duck in forum Qt Programming
    Replies: 4
    Last Post: 6th July 2006, 12:53
  5. Replies: 16
    Last Post: 7th March 2006, 15:57

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.