Bonjour a tous,

Dans le cadre d'un projet scolaire je dois coder un serveur tcp qui est censé réceptionner des structures sur le réseau via socket TCP. Je ne suis pas autorisé a utiliser de librairies type Qt ou Boost pour la sérialisation ou pour le réseau.

Mon problème est que les données que je reçoit sont corrompues. Excuser moi pour la longueure du code que je m'apprête a poster mais si vous voulez avoir une chance de m'aider il vous faut tout les éléments.

La structure que j'envoie ( c'est Packet) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
struct Header
{
  uint32_t      magic;
  uint32_t      checksum;
  uint32_t      timestamp;
  uint16_t      commandId;
  uint16_t      dataSize;
};
 
struct Packet
{
  struct Header header;
  char          data[128];
};
Je sérialise cette structure avec ces fonctions
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
41
42
43
44
45
46
47
48
49
 
unsigned char                           *Serialization::serialize_uint32(unsigned char *buffer, uint32_t arg)
{
  buffer[3] = (arg >> 24);
  buffer[2] = (arg >> 16);
  buffer[1] = (arg >> 8);
  buffer[0] = (arg);
  return (buffer + sizeof(uint32_t));
}
 
unsigned char                           *Serialization::serialize_uint16(unsigned char *buffer, uint16_t arg)
{
  buffer[1] = (arg >> 8);
  buffer[0] = (arg);
  return (buffer + sizeof(uint16_t));
}
 
unsigned char                           *Serialization::serialize_char(unsigned char *buffer, char arg)
{
  buffer[0] = (arg);
  return (buffer + sizeof(char));
}
 
unsigned char                           *Serialization::serialize_string(unsigned char *buffer, char *arg, int len)
{
  int                           i;
 
  i = -1;
  while (++i < len)
    buffer = serialize_char(buffer, arg[i]);
  return (buffer);
}
 
unsigned char                           *Serialization::serialize_header(unsigned char *buffer, struct Header& arg)
{
  buffer = serialize_uint32(buffer, arg.magic);
  buffer = serialize_uint32(buffer, arg.checksum);
  buffer = serialize_uint32(buffer, arg.timestamp);
  buffer = serialize_uint16(buffer, arg.commandId);
  buffer = serialize_uint16(buffer, arg.dataSize);
  return (buffer);
}
 
unsigned char                           *Serialization::serialize_packet(unsigned char *buffer, struct Packet& arg)
{
  buffer = serialize_header(buffer, arg.header);
  buffer = serialize_string(buffer, arg.data, arg.header.dataSize);
  return (buffer);
}
je désérialise ainsi :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
41
42
 
unsigned char                           *Serialization::deserialize_uint32(unsigned char *buffer, uint32_t *arg)
{
  memcpy((char*)arg, buffer, sizeof(uint32_t));
  *arg = ntohl(*arg);
  return (buffer + sizeof(uint32_t));
}
 
unsigned char                           *Serialization::deserialize_uint16(unsigned char *buffer, uint16_t *arg)
{
  memcpy((char*)arg, buffer, sizeof(uint16_t));
  return (buffer + sizeof(uint16_t));
}
 
unsigned char                           *Serialization::deserialize_char(unsigned char *buffer, char *arg)
{
  memcpy(arg, buffer, sizeof(char));
  return (buffer + sizeof(char));
}
 
unsigned char                           *Serialization::deserialize_string(unsigned char *buffer, char *arg, int len)
{
  memcpy(arg, buffer, len);
  return (buffer + len);
}
 
unsigned char                           *Serialization::deserialize_header(unsigned char *buffer, struct Header& arg)
{
  buffer = deserialize_uint32(buffer, &arg.magic);
  buffer = deserialize_uint32(buffer, &arg.checksum);
  buffer = deserialize_uint32(buffer, &arg.timestamp);
  buffer = deserialize_uint16(buffer, &arg.commandId);
  buffer = deserialize_uint16(buffer, &arg.dataSize);
  return (buffer);
}
 
unsigned char                           *Serialization::deserialize_packet(unsigned char *buffer, struct Packet& arg)
{
  buffer = deserialize_header(buffer, arg.header);
  buffer = deserialize_string(buffer, arg.data, arg.header.dataSize);
  return (buffer);
}
Le code d'envoi de mon client est :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
TcpSocket                     tcp;
Packet                        p;
char                          *serialized;
 
tcp.connectSocket("127.0.0.1", 4242);
p.header.magic = 0;
p.header.checksum = 1;
p.header.timestamp = 2;
p.header.commandId = 3;
p.header.dataSize = ss.str().length();
memset(p.data, 0, 128);
memcpy(p.data, "0", 2);
serialized = new char[sizeof(Header) + 2];
bzero(serialized, sizeof(Header) + 2);
Serialization::serialize_packet(serialized, p);
hexDump("serialized", serialized+1, sizeof(Header) + 2);
ret = tcp.write(serialized, sizeof(Header) + 3);
et mon serveur recoit ainsi (cette fonction est appellé par la boucle sur le select()) :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
 
int bav;
 
bav = socket->bytesAvailable();
buff = new char[bav];
socket->read(buff, bav);
hexdump("buff", buff, bav);
methodes read et send de ma classe Socket :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
 
int                     TcpSocket::read(char *buff, int len)
{
  int                   ret;
 
  ret = recv(this->_socket, buff, len, 0);
  return (ret);
}
 
int                     TcpSocket::bytesAvailable()
{
  int                   ret;
  char                  buff[65536];
 
  ret = recv(this->_socket, buff, 65535, MSG_PEEK);
  return (ret);
}
 
int                     TcpSocket::write(const std::string& buff, int len)
{
  int                   ret;
 
  ret = send(this->_socket, buff.c_str(), len, 0);
  return (ret);
}
voici les deux hexdumps :

client :
00 00 00 00 00 00 01 00 00 00 02 00 03 00 01 30 ...............0

server:
00 00 00 00 14 00 00 00 1c 00 00 00 1a 00 00 00 ...............

J'ai cherché pendant plusieurs jours avant de venir vous ennuyer avec mon problème.
En vous remerciant par avance