networking - Issue receiving and storing data in C++ -


i have written server application in c++ receives packet of data client application (which have not written myself) , prints data console. issue is, when try receive , store entire packet body @ once, data stored incorrectly, when packet body received , stored using multiple callings of recv(), store correctly.

regarding endianness, client , server both running on little endian machine, client sends data out little endian, , server reads without need conversion.

this packet client application sends server application:

00 03 23 00 57 6f 57 00  01 0c 01 f3 16 36 38 78 00 6e 69 57 00 42 47 6e  65 00 00 00 00 7f 00 00 01 05 41 44 4d 49 4e 

here structured view of packet:

cmd             00 error           03 pkt_size        23 00 gamename        57 6f 57 00 version1        01 version2        0c version3        01 build           f3 16 platform        36 38 78 00 os              6e 69 57 00 country         42 47 6e 65 timezone_bias   00 00 00 00 ip              7f 00 00 01 srp_i_len       05 srp_i           41 44 4d 49 4e 

these expected results printed out server application:

cmd:            0 error:          3 pkt_size:       35 gamename:       5730135 version1:       1 version2:       12 version3:       1 build:          5875 platform:       7878710 os:             5728622 country:        1701726018 timezone_bias:  0 ip:             127 0 0 1 srp_i_len:      5 srp_i:          admin 

here code having trouble with:

struct packet{     uint8   cmd;     uint8   error;     uint16  pkt_size;     uint32  gamename;     uint8   version1;     uint8   version2;     uint8   version3;     uint16  build;     uint32  platform;     uint32  os;     uint32  country;     uint32  timezone_bias;     uint8   ip[4];     uint8   srp_i_len;     uint8   srp_i[16]; };  packet data; recv(clientsocket, &data.cmd, 4, 0); // receive packet header recv(clientsocket, &data.gamename, 46, 0); // receive packet body  printf("%d\n", data.cmd); ... printf("%s\n", data.srp_i); 

the result:

cmd:            0 error:          3 pkt_size:       35 gamename:       5730135 version1:       1 version2:       12 version3:       1 build:          13846 (this goes wrong) platform:       1466527232 os:             1850163712 country:        101 timezone_bias:  35512 ip:             1 5 65 68 srp_i_len:      77 srp_i:          in 

if change code so:

recv(clientsocket, &data.cmd, 4, 0); // receive packet header recv(clientsocket, &data.gamename, 7, 0); // receive packet body recv(clientsocket, &data.build, 39, 0); // receive packet body 

the result:

... same expected results build:          5875 (fixed) platform:       1768816760 (goes wrong here instead) os:             1195507799 country:        25966 timezone_bias:  8323072 ip:             0 1 5 65 srp_i_len:      68 srp_i:          min 

and if make 1 last adjustment code, so:

recv(clientsocket, &data.cmd, 4, 0); // receive packet header recv(clientsocket, &data.gamename, 7, 0); // receive packet body recv(clientsocket, &data.build, 2, 0); // receive packet body recv(clientsocket, &data.platform, 37, 0); // receive packet body 

the result:

... same expected results build:          5875 platform:       7878710 os:             5728622 country:        1701726018 timezone_bias:  0 ip:             127 0 0 1 srp_i_len:      5 srp_i:          admin 

by calling recv() multiple times, received , stores data expected. have absolutely no idea why data stored incorrectly when calling recv() twice. please, somebody, enlighten me. thank you.

ps: sorry monster post of ugliness.

declare structure packed structure avoid alignment issues;

on windows use #pragma pack (1) (see msdn)

on gcc use __attribute__((packed))

to remove alignment problems. gcc support windows style pragmas compatibility. have at:

http://gcc.gnu.org/onlinedocs/gcc/structure_002dpacking-pragmas.html

edit

so example code below shows 1 packed structure inside untouched structure:

when compiled on x86_64-bit platform:

#include <iostream> #include <stdint.h> #include <string.h>  using namespace std;   uint8_t input[] = {     0x00,  0x03,  0x23,  0x00,  0x57,  0x6f,  0x57,  0x00,     0x01,  0x0c,  0x01,  0xf3,  0x16,  0x36,  0x38,  0x78,     0x00,  0x6e,  0x69,  0x57,  0x00,  0x42,  0x47,  0x6e,     0x65,  0x00,  0x00,  0x00,  0x00,  0x7f,  0x00,  0x00,     0x01,  0x05,  0x41,  0x44,  0x4d,  0x49,  0x4e };  struct __attribute__((packed)) packet{     uint8_t   cmd;     uint8_t   error;     uint16_t  pkt_size;     uint32_t  gamename;     uint8_t   version1;     uint8_t   version2;     uint8_t   version3;     uint16_t  build;     uint32_t  platform;     uint32_t  os;     uint32_t  country;     uint32_t  timezone_bias;     uint8_t   ip[4];     uint8_t  srp_i_len;     uint8_t  srp_i[16];  };  struct data {     long int foo;     short a;     uint8_t b;     struct packet p;     uint32_t bar; };  int main() {     struct packet p;     struct data d;      cout << "in: " << sizeof(input) << ", d: " << sizeof (d) << ", p: " << sizeof(p) << " d.p: " << sizeof(d.p) << endl;     memset(&p, 0, sizeof(p));     memcpy(&p, input, sizeof(input));     cout << (int) p.srp_i_len << endl;     cout << p.srp_i  << endl; }  $./foo in: 39, d: 72, p: 50 d.p: 50 5 admin 

Comments

Popular posts from this blog

SPSS keyboard combination alters encoding -

Add new record to the table by click on the button in Microsoft Access -

javascript - jQuery .height() return 0 when visible but non-0 when hidden -