Creating and sending data packets in C++

Let's say I want to send the following data to a socket using C++, all in one packet:
1
2
3
4
  fixed header:   { 0xe1,0xe2}          
   data1(int) :   {0x1e,0x25,0x71,0x80}               
   data2(int):    {0x00,0x00,0x00,0x23}          
   

What would the code typically look like to create and send the packet containing all this data with Initial value ?
Last edited on
Something along these lines:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <cstdint>
#include <vector>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>

struct data
{
    static constexpr std::size_t HEADER_SIZE = 2 ;
    static constexpr std::size_t DATA_SIZE = 4 ;

    std::uint32_t header[HEADER_SIZE] { 0xe1, 0xe2 } ;
    std::uint32_t data1[DATA_SIZE] { 0x1e, 0x25, 0x71, 0x80 } ;
    std::uint32_t data2[DATA_SIZE] { 0x00, 0x00, 0x00, 0x23 } ;

    static constexpr std::size_t PACKET_SIZE = HEADER_SIZE +  DATA_SIZE*2 ;
};

std::vector<std::uint32_t> to_ndr( const data& d )
{
    std::vector<std::uint32_t> ndr ; // eliminates possible padding
    
    // http://www.freebsd.org/cgi/man.cgi?query=htons&apropos=0&sektion=0&manpath=FreeBSD+10.1-RELEASE&arch=default&format=html
    for( auto& u32 : d.header ) ndr.push_back( ::htonl(u32) ) ; // convert to network byte order
    for( auto& u32 : d.data1 ) ndr.push_back( ::htonl(u32) ) ; // note: at the receiving end, use ::ntohl() to convert each std::uint32_t received
    for( auto& u32 : d.data2 ) ndr.push_back( ::htonl(u32) ) ; // to host representation and place the coverted values into an object of type data
    return ndr ;
}

int send_data( int fd_connected_socket, const data& d )
{
    const auto ndr = to_ndr(d) ;
    auto ptr = reinterpret_cast< const unsigned char* >( std::addressof( ndr.front() ) ) ;
    return ::send( fd_connected_socket, ptr, ndr.size() * sizeof( ndr[0] ), 0 ) ;
}
@JLBorges tnx ,if I use your code in class what should I do??
> if I use your code in class what should I do??

Nothing much. Though, burdening a class that holds some information with knowledge about sockets and network data representation concerns may not be a great design idea.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
#include <cstdint>
#include <vector>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>

class data
{
    public:
        static constexpr std::size_t HEADER_SIZE = 2 ;
        static constexpr std::size_t DATA_SIZE = 4 ;
        static constexpr std::size_t PACKET_SIZE = HEADER_SIZE +  DATA_SIZE*2 ;

        std::vector<std::uint32_t> to_ndr() const ;
        int send( int fd_connected_socket ) const ;

        std::uint32_t header[HEADER_SIZE] { 0xe1, 0xe2 } ;
        std::uint32_t data1[DATA_SIZE] { 0x1e, 0x25, 0x71, 0x80 } ;
        std::uint32_t data2[DATA_SIZE] { 0x00, 0x00, 0x00, 0x23 } ;
};

std::vector<std::uint32_t> data::to_ndr() const
{
    std::vector<std::uint32_t> ndr ; // eliminates possible padding

    // http://www.freebsd.org/cgi/man.cgi?query=htons&apropos=0&sektion=0&manpath=FreeBSD+10.1-RELEASE&arch=default&format=html
    for( auto u32 : header ) ndr.push_back( ::htonl(u32) ) ; // convert to network byte order
    for( auto u32 : data1 ) ndr.push_back( ::htonl(u32) ) ; // note: at the receiving end, use ::ntohl() to convert each std::uint32_t received
    for( auto u32 : data2 ) ndr.push_back( ::htonl(u32) ) ; // to host representation and place the coverted values into an object of type data

    return ndr ;
}

int data::send( int fd_connected_socket ) const
{
    const auto ndr = to_ndr() ;
    auto ptr = reinterpret_cast< const unsigned char* >( std::addressof( ndr.front() ) ) ;
    return ::send( fd_connected_socket, ptr, ndr.size() * sizeof( ndr[0] ), 0 ) ;
}
tank you.......
Topic archived. No new replies allowed.