从客户端发送大文件到服务器,我的逻辑正确吗?
我有一些相对较大的文件(1Mb-32Mb),我需要将它们从桌面应用程序发送到用 PHP 编写的脚本(借助名为 CodeIgniter 的 PHP 框架)。由于文件相当大,我正在考虑将这些文件分成小块/数据包,使用 Base64 对每个文件进行编码,并通过 JSON 格式的消息将它们一一发送。
我有一个关于如何将它们发送到服务器的想法,但我想先问你对此有何看法,如果你认为它可以,或者它是否有缺陷。
这里是。由于英语不是我的母语,我更喜欢将其公开为两个主体(客户端和服务器)之间的对话。我想你会更好地理解我正在尝试做的事情:
消息#1:
客户端:“嗨,服务器,我需要向您发送 -X- kbytes 长的文件。我将发送给您的文件的校验和为 -file_cheksum-"
服务器: "好的,我已准备好将其拆分为 -N- 个小数据包,每个数据包包含长度为 -Y- Kbytes,并发送它们一一放在这里,如果您在消息中提到您要将包裹发送到,我会记住如何处理它们 组装一个 ID 为 -FILE_ID- 的文件
消息 #2:
客户端: “这是 -N- 的第一个数据包,需要此数据包来组装名为 - 的文件FILE_ID-, 这是第一个数据包的校验和,以便您可以检查数据包是否已完好无损地到达”
服务器: “谢谢客户,我刚刚将其记在临时文件夹中。继续。”
...
消息 #N + 1:
客户端: “这是 -N- 的 -N- 数据包,这是最后一个数据包,需要汇编一个名为-FILE_ID-的文件, 这是最后一个数据包的校验和,以便您可以检查数据包是否已完好无损地到达”
服务器: “谢谢客户端,我刚刚将所有数据包组装在一起并验证了校验和; 生成的文件就OK了。 示例
每条消息都将通过 HTTP Post 发送,并使用 JSON 进行格式化,每个包含文件一部分的数据包将以 Base64 进行编码,然后由服务器进行解码。以下是从客户端发送的消息的 向服务器发送:
{
"request": "set-packet",
"id": " [ file ID ] ",
"packet":
{
"file": " [ here goes the packet in Base64 ] ",
"checksum": " [ here goes the checksum ] "
}
}
如果一切正常,服务器会响应:
{
"status": "ok",
"message": "packet memorized"
}
如果出现问题,服务器会响应,例如:
{
"status": "error",
"message": "Checksum doesn't match, try again"
}
您认为这个逻辑是正确的还是有缺陷的,您会对其进行任何改进吗?
谢谢
I have some relatively large files (1Mb-32Mb) and I need to send them from a desktop app to a script written in PHP (with the aid of a PHP framework called CodeIgniter). Since the files are pretty big I'm considering to split those files into small chunks / packets, encode each of them with Base64 and send them one by one through a JSON-formatted message.
I've an idea about how to send them to the server, but I'd like to ask you first what do you think about that, if you think that it's allright or if it's flawed.
Here it is. Since English is not my native language I prefer to expose it as a dialoge between two subjects, a client and a server. I though you would understand a little bit better what I'm trying to do:
Message #1:
Client: "Hi server, I need to send you a -X- kbytes long file. The file I'll send you will have a checksum of -file_cheksum-"
Server: "Ok I'm ready to receive it. Split it in -N- small packets, each with a length of -Y- Kbytes, and send them here one by one, I'll remember what to do with them if in your message you mention that your are sending packages to
assemble a file with the ID -FILE_ID- "
Message #2:
Client: "Here's the first packet of -N-, this packet is required to assemble a file named -FILE_ID-,
and here's the checksum of the first packet so you can check if the packet has arrived in good shape"
Server: "Thank you client, I've just memorized it in a temporary folder. Keep going."
...
Message #N + 1:
Client: "Here's the -N- packet of -N-, this is the last packet and it's required to assemble a file named -FILE_ID-,
and here's the checksum of the last packet so you can check if the packet has arrived in good shape"
Server: "Thank you client, I've just assembled together all the packets and verified the checksum;
the resulting file is OK. Good job."
Each message will be sent via HTTP Post and will be formatted with JSON, and each packet containing a part of the file would be encoded in Base64 and then decoded by the server. Here's an example of a message sent from the client to the server:
{
"request": "set-packet",
"id": " [ file ID ] ",
"packet":
{
"file": " [ here goes the packet in Base64 ] ",
"checksum": " [ here goes the checksum ] "
}
}
If everything is allright, the server would respond:
{
"status": "ok",
"message": "packet memorized"
}
If there's a problem, the server instead would respond for example:
{
"status": "error",
"message": "Checksum doesn't match, try again"
}
What do you think about this logic? Is it correct or flawed, and would you make any improvements on it?
Thank you
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我相信您建议的解决方案太过分了。您正在应用程序层(HTTP)上进行传输协议级别检查(数据包校验和)。是的,它可以工作,但它毫无意义地使工作加倍,数据包校验和已经在 TCP/IP 级别上发生(早在 HTTP 抽象级别之前)。
我也会按照 Dagon 的建议,使用用于文件传输的协议:FTP(或 SSH)。任何共享主机都应该有 ftp 或 ssh(否则,您如何首先获取服务器上的任何文件:P)。查看 ftp http://be.php.net/manual/en/book。 ftp.php 和 ssh http://be.php.net/manual/en/book.ssh2.php php 扩展。
干杯
I believe your suggested solution is way too much overkill.. You're doing transmission protocol level checks (packet checksums) on an application layer (HTTP). Yes, it could work, but it's litterly doubling the work for nothing, the packet checksums are already happening at a TCP/IP level (long before the HTTP abstraction level).
I would also go for what Dagon suggested, use a protocol intended for file transfer: FTP (or SSH). Any shared host SHOULD have either ftp or ssh (else, how do you get any of your files on the server in the first place :P). Checkout the ftp http://be.php.net/manual/en/book.ftp.php and ssh http://be.php.net/manual/en/book.ssh2.php extensions of php.
Cheers
只需使用简单的 HTTP POST 上传 并确保upload_max_filesize(php.ini 设置)至少为 32M。这里没有必要重新发明轮子。
还有一个您可能会觉得有用的 CI 类。
Just use simple HTTP POST uploads and make sure upload_max_filesize (php.ini setting) is at least 32M. Not point in reinventing the wheel here.
There is also a CI class that you might find useful.