sockets - 将 "Large"数据文件传输到服务器的简单 TCP 协议(protocol)

标签 sockets tcp protocols network-protocols

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

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

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

有人可以推荐一种协议(protocol),我可以使用它来执行“流式传输”或将部分数据发送到服务器的过程吗?

协议(protocol)需要相对简单并且不会占用很多内存资源,如果您知道为小型嵌入式设备设计的库,那也很好。该协议(protocol)还应该易于在接收服务器上实现,最好运行 .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,就此而言)对您在代码中发送字节的方式没有概念。因此,所有要做的就是循环读取文件数据,使用适当大小的内存缓冲区,在每次读取后通过套接字发送该缓冲区的内容,直到遇到 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 ...

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

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.

不要必须在一个字符串中一次发送所有内容。您可以根据需要将其分解为多个字符串/发送。 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 非常适合。

关于sockets - 将 "Large"数据文件传输到服务器的简单 TCP 协议(protocol),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28791550/

相关文章:

python - 在 Python 中使用一个套接字接收和发送消息

c++ - 使用 boost 的 async_write 的异步 tcp 服务器会导致错误的文件描述符

javascript - 我可以在 &lt;script src ="ftp://"> 中使用 ftp 站点吗

java - 为什么第二次拒绝连接?

sockets - TCP监听器和套接字之间的区别

sockets - 原始套接字接收缓冲区

c - 当 tcp 服务器等待数据时,如何让程序每 10 毫秒读取一次传感器

c - 为什么 recv() 改变了不相关的变量

objective-c - @protocol 扩展@protocol

c - 我不断收到错误消息 : "Conflicting types for ' sqrt' "