Это скорее запрос на подтверждение, чем вопрос, поэтому я буду кратким. (Я не на своем компьютере и поэтому не могу просто внедрить это решение для тестирования).
Я пишу программу для отправки файла изображения, снятого через веб-камеру (вместе с метаданными) с raspberryPi на мой компьютер.
Я выяснил, что размер изображения составляет около 130 КБ, заголовок пакета — 12b, а связанные метаданные — еще 24b. Хотя я могу увеличить размер изображения в будущем, когда у меня будет рабочий прототип.
В настоящее время я не могу получить весь этот пакет успешно, так как, после отправки его на ПК, я получаю только около 64 КБ в буфере.
Я предположил, что это потому, что по какой-либо причине размер буфера по умолчанию для сокета объявлен как:
SOCKET sock = socket(PF_INET, SOCK_STREAM, 0);
64 КБ (пожалуйста, кто-то может уточнить это, если вы «в курсе»)
Итак, чтобы решить эту проблему, я намерен увеличить размер сокета до 1024 КБ с помощью команды setsockopt (x ..).
Кто-нибудь может подтвердить, что мой диагноз проблемы и предложенное решение верны?
Я задаю этот вопрос, так как сейчас у меня нет компьютера, и я не могу попробовать его, пока не вернусь домой.
Скорее всего, это не имеет ничего общего с буферами сокетов, но с тем фактом, что recv()
а также send()
не нужно получать и отправлять все данные, которые вы хотите. Проверьте возвращаемое значение этих вызовов функции, оно показывает, сколько байтов было фактически отправлено и получено.
Лучший способ справиться с «короткими» операциями чтения / записи — это поместить их в цикл следующим образом:
char *buf; // pointer to your data
size_t len; // length of your data
int fd; // the socket filedescriptor
size_t offset = 0;
ssize_t result;
while (offset < len) {
result = send(fd, buf + offset, len - offset, 0);
if (result < 0) {
// Deal with errors here
}
offset += result;
}
Используйте аналогичную конструкцию для получения данных. Обратите внимание, что одним из возможных условий ошибки является то, что вызов функции был прерван (errno = EAGAIN
или же EWOULDBLOCK
), в этом случае вы должны повторить команду send, во всех остальных случаях вы должны выйти из цикла.
Других решений пока нет …