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) :
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 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 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
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); }
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
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); }
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
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);
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 int bav; bav = socket->bytesAvailable(); buff = new char[bav]; socket->read(buff, bav); hexdump("buff", buff, bav);
voici les deux hexdumps :
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); }
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
Partager