C++ Socket envoi de structures s�rialis�es
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:
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:
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:
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:
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:
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:
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