Я написал серверное приложение на C++, которое получает пакет данных из клиентского приложения (которое я сам не написал) и выводит данные на консоль. Проблема заключается в том, что когда я пытаюсь получить и сохранить весь пакет сразу, данные хранятся некорректно, однако, когда тело пакета принимается и сохраняется с помощью нескольких вызовов recv(), оно хранится правильно.Получение и хранение данных в C++
Что касается контентоспособности, клиент и сервер работают на маленькой конечной машине, клиент отправляет данные как минимальные, а сервер читает их без необходимости преобразования.
Это пакет, который клиентское приложение отправляет к серверному приложению:
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
Вот структурированный вид пакета:
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
Эти ожидаемые результаты, которые должны быть распечатаны приложением сервера:
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
Вот код, который у меня возникли проблемы с:
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);
Результат:
cmd: 0
error: 3
pkt_size: 35
gamename: 5730135
version1: 1
version2: 12
version3: 1
build: 13846 (this is where it all goes wrong)
platform: 1466527232
os: 1850163712
country: 101
timezone_bias: 35512
ip: 1 5 65 68
srp_I_len: 77
srp_I: IN
Если изменить код так:
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
Результат:
... same expected results
build: 5875 (fixed)
platform: 1768816760 (goes all wrong here instead)
os: 1195507799
country: 25966
timezone_bias: 8323072
ip: 0 1 5 65
srp_I_len: 68
srp_I: MIN
И если я сделать последнюю корректировку кода, например, так:
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
Результат:
... 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
Вызов recv() multiple раз, он получил и сохраняет данные точно так, как ожидалось. Я абсолютно не знаю, почему данные хранятся некорректно, только дважды вызывая recv(). Пожалуйста, кто-нибудь, просветите меня. Спасибо.
PS: Извините за пост монстра уродства.
Компилятор C оставил пробелы в вашем 'struct packet' по соображениям оптимизации. Однако пакет, отправленный на проводе, не имел пробелов. Если бы я делал это, я бы «recv» пакет в буфере временного байта, а затем вручную считывал каждое поле из буфера и записывал его в мою собственную структуру, избегая всех проблем выравнивания структуры. Ваш код также принимает общее соответствие с удаленным хостом. – NovaDenizen