Я хочу избежать на первый взгляд обычной практики выделения огромного буфера и надеюсь, что пакет не станет больше.
Не уверен, что вы подразумеваете под этим.UDP-пакет приходит сразу, поэтому начальное целое число точно указывает, насколько большим должен быть ваш буфер;он не будет «расти» после его прибытия.
Поскольку вы добавляете нулевой символ, вам необходимо учитывать это при расчете длины:
int msglen = sizeof(int) + txtlen + 1;
Будьте осторожны, когда выиспользуйте realloc()
:
m = realloc (m, msglen);
Если realloc
не удастся, он установит m
в ноль.Это означает, что вы потеряете свою единственную ссылку на память, которая была первоначально выделена для него, поэтому вы никогда не сможете free()
это.Попробуйте что-то вроде этого:
void *tmp = realloc(m, msglen)
if (tmp == null) {
// handle the error
}
m = tmp;
И когда вы печатаете данные, m->text
вычисляет адрес первого символа, поэтому вы можете использовать
printf("%s\n", m->text);
В качестве альтернативыВы можете определить свою структуру с фиксированным размером, как
struct message {
int length;
char *text;
}
Тогда вы можете использовать malloc()
для выделения (только) вашего текстового буфера:
struct message m;
recv(sock, &m.length, sizeof(int), MSG_WAITALL | MSG_PEEK);
m.text = malloc(m.length + 1); // +1 for the null that you'll append
read(sock, m.text, m.length);
m.text(m.length) = '\0';
printf("%s\n", m.text);
free(m.text);
Удачи вам с вашимпроект - сетевое программирование - это всегда опыт обучения!