Вы спрашиваете об этом куске кода:
memcpy(&dest[bytes], (void*)htonl(cbytes), sizeof(uint32_t));
Нет, это совсем не правильно. Вы конвертируете возвращаемое значение htonl
в указатель. Однако это неверный указатель. У вас есть , чтобы иметь объект типа uint32_t
для отправки:
uint32_t cbytes32 = htonl(cbytes);
memcpy(&dest[bytes], &cbytes32, sizeof(uint32_t));
Это можно сделать и в одну строку, в современном C, используя составной литерал , чтобы создать массив из одного uint32_t
inline:
memcpy(&dest[bytes], (uint32_t[]){ htonl(cbytes) }, sizeof(uint32_t));
но синтаксис действительно не выглядит лучше.
Чтобы прочитать его, вам нужно прочитать его для объекта типа uint32_t
, затем ntohl
его и возвращаемого значения, которое вы можете сохранить в size_t
:
uint32_t size32;
size_t size;
memcpy(&size32, src, sizeof size32)
size = ntohl(size32);
Тогда я был бы особенно осторожен с тем, что вы используете, возможно, 64-битный size_t
в другом месте, но урезаете его до 32 бит. Это может быть хорошо, но это должно быть задокументировано. 64 бита должно хватить всем, но, к сожалению, функции htonll
нет.
Наконец, вместо &dest[bytes]
вы можете написать dest + bytes
для меньшего количества нажатий клавиш. И еще меньше, вы можете сделать еще один указатель:
uint8_t *cur = dest;
memcpy(cur, iv, sizeof iv);
cur += sizeof iv;
uint32_t cbytes32 = htonl(cbytes);
memcpy(cur, &cbytes32, sizeof cbytes32);
cur += sizeof cbytes32;
memcpy(cur, ciphertext, cbytes32);
cur += cbytes32;
memcpy(cur, tag, sizeof tag);
cur += sizeof tag;
size_t nbytes = cur - dest;
Обратите внимание, что если вы используете потоковый сокет (TCP), обычно нет необходимости копировать их в промежуточный буфер - просто отправьте 4, 8 байтов, используя отдельный вызов read
- или, по крайней мере, не пытайтесь копировать массив long в тот же буфер после вызова размера.