将 "Large" 数据文件传输到服务器的简单 TCP 协议

A Simple TCP Protocol to Transfer a "Large" Data File to a Server

给反对者的消息:请阅读问题,我正在开发一个小型嵌入式设备。如果您不熟悉此类设备的局限性,请转到另一个问题而不是投反对票!!!!

我正在使用内存有限的小型嵌入式设备,我需要从该设备向服务器发送一个大文件。因此我不能简单地使用HTTP POST,这要求我在发送之前将整个文件加载到内存中。

嵌入式设备有 UDP 和 TCP 套接字,但要发送 HTTP POST,例如,我需要创建一个包含 HTTP HEADERS 和数据的字符串。由于设备没有 HTTP 协议或其他可用作 API 的协议。

有人可以推荐我可以用来执行 "streaming" 过程或将部分数据发送到服务器的协议吗?

该协议需要相对简单并且不会占用很多内存资源,如果您知道为小型嵌入式设备设计的库也很好。该协议还应该易于在接收服务器上实现,最好是 运行 .Net

I am working with a small embedded device that has limited memory and I need to send a large file to a server from this device. Hence I cannot easily use HTTP POST which requires me to load the entire file into memory before sending.

不,POST 不需要。它所需要的只是您发送的 HTTP Content-Length header 与您为实际文件数据发送的字节数相匹配。或者您可以使用 HTTP 1.1 的 chunked 传输编码,它不使用 Content-Length header(因此您不需要提前知道文件大小)。 POST(或 HTTP,就此而言)没有 HOW 您在代码中发送字节的概念。所以所有要做的就是在循环中读取文件数据,使用 appropriate-sized 内存缓冲区,在每次读取后通过套接字发送该缓冲区的内容,直到你命中 EOF。

例如 (pseudo-code):

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 ...

即使是功能强大的台式机也必须这样做,因为通常无法将整个文件一次放入内核缓冲区,因此必须相应地循环发送。

The embedded device has UDP and TCP sockets, but to send a HTTP POST for example, I need to create a string that contains the HTTP HEADERS and the Data.

不要必须在一个字符串中一次发送所有内容。您可以根据需要将其分成多个 strings/sends。 TCP 是一种流式传输,它不关心您执行了多少次发送,只要您发送的字节顺序正确即可。您可以一次发送 1 个字节来满足它的所有需求(虽然效率不高,但可以工作)。

As the device does not have the HTTP Protocol or other protocols available as APIs.

不需要。由于 HTTP 位于 TCP 之上,并且您可以访问 TCP 套接字 API,因此您可以手动实现 HTTP。

Can someone recommend a protocol I could use to perform the process of "streaming" or sending the data in parts to the server?

HTTP 已经做到了这一点。

The protocol needs to be relatively simple and not use up many memory resources, and if you know of a library designed for small embedded device that would be good also. The protocol should also be simple to implement on the receiving server, preferable running .Net

HTTP 非常适合。