Я работаю с небольшим встроенным устройством с ограниченной памятью, и мне нужно отправить большой файл на сервер с этого устройства. Следовательно, Я не могу легко использовать HTTP POST, который требует, чтобы я загрузил весь файл в память перед отправкой.
No, POST
не требует этого. Все, что требуется, - это то, что заголовок HTTP Content-Length
, который вы отправляете, соответствует количеству байтов, отправляемых для фактических данных файла. Или вы можете использовать кодировку передачи HTTP 1.1 chunked
, которая не использует заголовок Content-Length
(так что вам не нужно заранее знать размер файла). POST
(или HTTP, если на то пошло) не имеет понятия КАК вы отправляете байты в свой код. Таким образом, все, что нужно сделать, это прочитать данные файла в цикле, используя буфер памяти соответствующего размера, посылая содержимое этого буфера через сокет после каждого чтения, пока не нажмете EOF.
Например (псевдо-код):
sckt = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
connect(sckt, "hostname", 80)
send(sckt, "POST /resource HTTP/1.0\r\n")
send(sckt, "Content-Type: application/octet-stream\r\n"); // or the actual file type
send(sckt, "Content-Length: " + string(the file size) + "\r\n")
send(sckt, "\r\n")
byte buffer[256] // use whatever buffer size is appropriate for your device
do
{
numread = read(file, buffer, sizeof(buffer));
if (numread <= 0) break;
send(sckt, buffer, numread);
}
while (true);
read HTTP response from sckt ...
Или:
sckt = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
connect(sckt, "hostname", 80)
send(sckt, "POST /resource HTTP/1.1\r\n")
send(sckt, "Content-Type: application/octet-stream\r\n"); // or the actual file type
send(sckt, "Transfer-Encoding: chunked\r\n")
send(sckt, "\r\n")
byte buffer[256] // use whatever buffer size is appropriate for your device
char hex[12]
do
{
numread = read(file, buffer, sizeof(buffer));
if (numread <= 0) break;
sprintf(hex, "%x", numread);
send(sckt, string(hex) + "\r\n")
send(sckt, buffer, numread)
send(sckt, "\r\n")
}
while (true);
send(sckt, "0\r\n");
send(sckt, "\r\n");
read HTTP response from sckt ...
Даже мощные настольные компьютеры должны делать это таким образом, так как весь файл обычно не могут быть помещены в ядро буфер в одно и то же время, поэтому отправка должна выполняться соответственно.
Введенное устройство имеет UDP и TCP-сокеты, но для отправки HTTP POST, например, мне нужно создать строку, содержащую HEADERS и данные.
Вы НЕ должны послать все в одно время в одной строке. Вы можете разбить его на несколько строк/отправок по мере необходимости. TCP - это потоковый транспорт, ему не важно, сколько отправок вы выполняете, если отправленные вами байты находятся в правильном порядке.Вы можете отправлять по 1 байт за все, что ему нужно (хотя это было бы не очень эффективно, но это сработало).
Поскольку устройство не имеет протокола HTTP или других протоколов, доступных в качестве API.
Этого не нужно. Поскольку HTTP находится поверх TCP, и у вас есть доступ к API сокетов TCP, вы можете реализовать HTTP вручную.
Может кто-то рекомендовать протокол, который я мог бы использовать для выполнения процесса «потоковой передачи» или отправки данных по частям на сервер?
HTTP уже делает именно это.
Протокол должен быть относительно прост и не использовать много ресурсов памяти, и если вы знаете библиотеку, предназначенную для небольших встроенных устройств, которые также будут хороши. Протокол также должен быть прост для реализации на принимающем сервере, предпочтительный запуск .Net
HTTP отлично подходит для этого.
HTTP POST не требует загрузки всего файла в память перед отправкой. – EJP
Как было сказано в моем вопросе, мне нужно создать пакет HTTP POST с нуля, поскольку я использую небольшое встроенное устройство, которое не имеет реализованного протокола HTTP. Конечно, вы правы, но, скорее всего, вы говорите о том, как вы используете его в мощной операционной системе, которая имеет API для использования, который обрабатывает все это. Я кодирую в raw C, с RTOS, который не предлагает таких функций. – Remixed123
Ничего не объясняет. Вам все равно не нужно загружать весь файл в память, и если это ваше единственное возражение против использования HTTP POST, проблема решена. Вы также можете использовать HTTP PUT. Быть грубым для людей, которые пытаются помочь вам, - это не рациональная стратегия. – EJP