Я работаю над проектом, основанным на отслеживании движений с использованием 3 плат ESP32, которые анализируют пакеты PROBE. Эта функция вызывается для каждого ESP последовательно. Итак, сначала я соединяюсь со всеми ESP, затем вызывается эта функция и начинает считывать из соединения количество пакетов, а затем каждый пакет. Проблема состоит в том, что когда я пытаюсь отправить список из 200 пакетов от каждого ESP, сервер правильно получает количество пакетов первого ESP, но затем начинает читать пакеты и получает только их часть (получает корректно около 140 из 200 всего, а затем часть пакета 141), а затем вылетает. Платы могут отправлять все пакеты, но затем не получают ACK от сервера, так как он вышел из строя. Я не могу понять, почему сервер продолжает сбой при тестировании с большим количеством пакетов, в то время как он отлично работает с одной платой и небольшим количеством пакетов
int recvPseq(SOCKET s) {
uint32_t numP;
unsigned char netP[4];
int res;
res = recv(s, (char *)netP, 4, 0);
if (res > 0) {
if (res != 4) {
cout << "Number of packet not entirely received! Only: " << res << " bytes" << endl;
return 0;
}
}
else if (res == 0) {
cout << "Socket closed by the client" << endl;
return 0;
}
else {
cout << "Error while receving the number of packets: " << WSAGetLastError() << endl;
return 0;
}
/* NumP contains the number of packets */
numP = ntohl(*(uint32_t*)netP);
cout << "Number of packets: " << numP << endl;
/* Reading the packets */
for (int i = 0; i < numP; i++) {
unsigned char recvbuffer[55];
res = recv(s, (char *)recvbuffer, 55, 0);
if (res > 0) {
if (res != 55) {
cout << "Packet " << i + 1 << " not entirely received! Only: " << res << " bytes" << endl;
return 0;
}
}
else if (res == 0) {
cout << "Socket closed by the client" << endl;
return 0;
}
else {
cout << "Error while receving the number of packets: " << WSAGetLastError() << endl;
return 0;
}
cout << "Received " << i + 1 << endl;
}
return 1;
}
Вы не читаете правильно из сокетов TCP. призвание recv(buflen=X)
может вернуть 0..X байт. recv()
не будет ждать, пока весь буфер заполнится данными.
типично recv()
должен вызываться в цикле, пока не будет получено достаточно данных. Каждый получатель TCP (сервер или клиент) должен сделать это. Обойти это невозможно. Так работает TCP. TCP всегда ориентирован на байты. Там нет границ пакетов. Вы будете наблюдать все виды артефактов сетевой инфраструктуры и буферов, используемых вдоль пути, при просмотре фактически полученного количества байтов на recv()
вызов.
Других решений пока нет …