даже не гарантируется, что 4 байта будут целиком.может поступить только 2 байта информации о размере, если предположить, что информация о размере поступила, может использоваться 2 байта, а остальные целочисленные данные будут отброшены.ожидание 4 байтов для буфера чтения может привести к бесконечному ожиданию, если в буфере доступно только 3 байта (например, если общий буфер имеет длину 7 байтов или 4077 байтов).
Если у вас естьДескриптор длиной 4 байта, вы всегда должны читать как минимум 4 байта, потому что отправитель должен был записывать эти байты в каждом сообщении, которое получает ваш сервер.Если вы не можете их получить, возможно, возникла проблема при передаче.Я действительно не могу понять вашу проблему.
В любом случае, я предлагаю вам не использовать никакой разделитель.Поместите заголовок в блоки данных, которые вы передаете, и используйте буфер для восстановления потока пакетов.
Вы должны по крайней мере прочитать заголовок пакета, чтобы определить его длину.
Вы можете определитьБазовая структура пакета:
struct packet{
uint32 id;
char payload[MAX_PAYLOAD_SIZE];
};
Данные, которые вы читаете из сокета и сохраняете их в буфере:
struct packet buffer;
Затем вы можете прочитать данные из сокета: int n;n = read (newsocket, & buffer, sizeof (uint32) + MAX_PAYLOAD_SIZE);
read возвращает количество прочитанных байтов.Если вы точно прочитали пакет от отправителя, то n = id.В противном случае, возможно, вы прочитаете больше данных (например, отправитель отправил вам больше пакетов).Если вы получаете поток данных, разделенных на блоки (представленные структурами пакетов), вы можете использовать массив пакетов для хранения всего полученного пакета и временный буфер для управления входящими фрагментами.Что-то вроде:
буфер структурных пакетов [MAX_PACKET_STORED];char temp_buffer [MAX_PAYLOAD_SIZE + 4];
int n;n = read (newsocket, & buffer, sizeof (uint32) + MAX_PAYLOAD_SIZE);
// здесь предположим, что получили пакет с полезной нагрузкой 100 байт + длина 32 бита + 100 байт // фрагменты следующего пакета.// затем:
int first_pack_len, second_pack_len;
first_pack_len = *((uint32 *)&temp_buffer[0]); //retrieve packet length
memcpy(&packet_buffer[0], temp_buffer, first_pack_len + sizeof(uint32)) //store the first packet into the array
second_pack_data_available_in_buffer = n - (first_pack_len + sizeof(uint32)); //total bytes read minus length of the first packet read
second_pack_len = *((int *)&temp_buffer[first_pack_len + sizeof(uint32)]);
Я надеюсь, что все было достаточно ясно.Но, возможно, я неправильно понимаю ваш вопрос.Обратите также внимание на то, что если у двух конечных систем, имеющих связь, могут быть разные порядковые номера, то лучше использовать функцию длины htonl / ntohl при отправке / получении значения длины.Но это другой вопрос)