Re: how to create a network buffer ?
aki wrote:
On May 1, 1:59 pm, James Kanze <james.ka...@gmail.com> wrote:
On Apr 30, 6:17 pm, aki <akhileshrawat...@gmail.com> wrote:
i am writing codes for implementing network protocols.
i have written a method which is receiving a packet from network.
i have assumed that the packet i will receive will be of type char*.
i need to test my method and
for that i want to create a network buffer which will contain a
packet of format as->
example of Configuration req packet
uint8_t code;
uint8_t identifier;
uint16_t length;
option1
option2
.....
option n
for eg option1 can be.... AuthProtocol with fields as
uint8_t type;
uint8_t length;
uint16_t authpro;
i was tryin to do like this.. but it has a limitation....
supposing packet contains header and only one option..
it will need 8 byte aas a whole..
char *buffer=new char(8);// allocating buffer with required memory
No. Here, you've allocated a single char, and initialized it
with the value 8. what you probably want is:
std::vector< char > buffer( 8 ) ;
Although for various reasons, I find it easier to work with an
std::vector< unsigned char > for this sort of thing (unless the
protocol is text based).
If you're generating a buffer for output, just declaring:
std::vector< unsigned char > buffer ;
and using push_back to insert the values is generally
sufficient. In this case, something like:
buffer.push_back( code ) ;
buffer.push_back( identifier ) ;
size_t lengthOffset - buffer.size() ;
buffer.push_back( 0 ) ; // Save space for length...
buffer.push_back( 0 ) ;
insertOptions( buffer ) ;
assert( buffer.size() < 1 << 16 ) ;
buffer[ lengthOffset ] = buffer.size() >> 8 ;
buffer[ lengthOffset + 1 ] = buffer.size() ;
(This assumes Internet format for unsigned integers.)
memset(buffer,1,1); // setting code field as 1
You don't need memset to set a single byte.
memset(buffer+1,4,1); // setting identifier as 4
memset(buffer+2,25,2); // here i am not able to put length in 2 byte
field as memset works with only one byte ...
Memset cannot be used for anything other than a stream of bytes.
Forget it (and memcpy) for generating buffers for protocols.
Just use a vector< unsigned char >, as above, then, to pass it
to the socket interface:
reintepret_cast< char* >( &buffer[ 0 ] ) ;
(Generally, reintepret_cast's are not a very good idea, but this
is the exception which confirms the rule.)
well i am a newbie in this field... but i was unable to do by the
way you told..actually i have never
worked with vectors .......
It's by far the simplest way.
FWIW: implementing network protocols is generally not for
beginners. The pure text protocols (HTTP, NNTP, SMTP, etc.)
aren't that difficult, but the others require a good deal of
mastery of the low-level representations.
i tried with this way ....
// putting both option in a structure....hust for testing....
char *buffer=new char(8); // it workin.like this...
As I said above, this allocates a single char, initialized with
the value 8. What you probably want is:
char* buffer = new char[ 8 ] ;
I would still very strongly recommend using unsigned char,
rather than plain char, for such things.
struct test
{
uint8_t type;
uint8_t length2;
uint16_t authprot;
uint8_t type1;
uint8_t length1;
uint16_t mru;
} *k;
Note that the size of this struct may be more than 8. There's
no guarantee that it will fit into a buffer of 8 bytes. (In
this particular case, the probability is very, very slim of this
being a problem. But in the general case, it has to be
considered, and correcting other, very real problems will also
eliminate any risk of problems because of this.)
k=(struct test*)buffer;
k->type=3;
k->length2=4;
k->authprot=2;
k->type1=1;
k->length1=4;
k->mru=15;
Which gives you an image of the struct in internal format. No
guarantee what so ever that it corresponds to the format on the
line. (If you are running on an Intel processor, and the
protocol is an Internet protocol, it is in fact almost certain
that this doesn't work.
// printinting the buffer
for(int i=0;i<8;i++)
{
cout<<"buffer:"<<(uint16_t)buffer[i]<<endl;
}
output is like this..
buffer:3
buffer:4
buffer:2
buffer:0
buffer:1
buffer:4
buffer:15
buffer:0
Any comments on this..
What does it have to do with the format on the line? Cout
converts internal format, not some external format defined by a
protocol. For the moment, you've not formatted anything, and
you have undefined behavior in several places (which means that
while it may give the impression of working in simple cases, it
can foul up badly depending on random factors).
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34