使用C++将文件上传到Web服务器

4
我想从客户端位置上传文件到服务器。目前,我有一个客户端-服务器套接字程序,可以通过它发送/接收文件,但我想改进它。
我的想法是使用HTTP PUT / POST从客户端(大部分编码在客户端)向服务器传输文件。由于我对HTTP编程一无所知,因此我需要一些指导来实现这一点。我想使用C++和BSD套接字来完成这项工作,而不使用其他库。我的目标是使用HTTP POST / PUT请求向服务器发送如下表单,并将文件“main.cpp”上传到服务器。
PUT http://localhost/ HTTP/1.0
Host: localhost
Content-type: form-data
Content-length: 90
FileUpload: /Users/SG/files/main.cpp

我能够编写一个虚拟程序,从客户端进行PUT操作,运行Apache的Web服务器返回HTTP 200。目前我无法理解以下两点,它们可能有些相关:
  1. 如何在上述表单中指定要从客户端上传的文件?
  2. 如果我理解正确,文件将在客户端处被读取,然后文件内容将被发送到服务器,在那里,服务器端脚本将从客户端读取字节并创建文件的副本。这是正确的吗?
任何帮助都将不胜感激。
谢谢, Sayan

“我想改进它”这句话听起来很不错,你应该把它加到“你杜撰的新编程术语”问题中http://stackoverflow.com/questions/2349378/new-programming-jargon-you-coined :) - Eugen Constantin Dinca
我想我是从别人那里复制过来的 ;) - Sayan
3个回答

4
如所述,这是不可能的。C++本身没有套接字API。(编辑:随着BSD套接字API的添加,现在已经成为可能)。
您的实现可能提供特定于操作系统的套接字API,在这种情况下,您的问题归结为“如何编写HTTP客户端?”答案是(a)不要,或者(b)仔细阅读HTTP规范并按照指示执行。基本步骤如下:
1. (可能)解析URL并使用gethostbyname获取IP地址。 2. 使用connect打开TCP套接字。 3. 使用send编写请求(您已经知道它是什么样子的)。 4. 使用read读取响应。 5. 关闭连接。
困难的部分是强大地解析响应,因为有很多要担心的功能。如果您的客户端与特定服务器绑定,则其响应将相当可预测,并且您可以忽略HTTP规范的很多内容(至少在更改服务器配置、更新其软件等之前)。
如果你在完成前已经想放弃,那么有一些非常好的HTTP库可供使用,比如libcURL

使用HTTP POST不也可以吗?我可以将包含HTTP POST请求(以及其他信息)的字符串发送到服务器上吗?我已经使用HTTP GET从服务器下载文件,所以我想应该有一种方法可以使用纯C++上传文件吧(?)。 - Sayan
如果没有套接字库,甚至无法连接到HTTP服务器。C++本身没有套接字库,因此需要使用一些特定于操作系统的库来获取套接字。 - Charles Salvia
是的,我现在明白你的意思了。我已经修改了我的问题。 - Sayan
@Sayan:你可以很容易地编写一个非常简单的HTTP POST客户端...但它会有漏洞。有许多边缘情况。如果服务器不是HTTP 1.1,或者返回重定向代码,或者存在意外的透明代理执行奇怪的操作,你该怎么办?如果你自己编写,未来几年你将花费许多时间修复小而烦人的问题。 - Zan Lynx
是的,我同意未来可能会变得混乱。但是,我仍然希望能够在这方面有一个方向。 - Sayan
谢谢 Steve。我会跟进的。 - Sayan

2
我想使用C++来完成这个任务,不使用任何库或system()调用。
套接字编程总是需要系统调用。C++是一种非常通用的语言。ISO语言定义没有指定任何关于套接字或网络编程的内容,因此为了做到这一点,您需要依赖于另一个系统特定的库/标准,例如UNIX/Linux上的BSD套接字API。通常,在C++中,您会使用一个更高级别的第三方库来包装这些较低级别的系统调用,例如Boost.ASIO。然而,即使这也需要一些学习,更不用说在套接字之上正确实现HTTP标准本身了。

啊哈,我现在明白了Steve说的C++没有套接字API是什么意思。是的,我正在使用BSD套接字……所以让我相应地重新提出我的问题。谢谢。 - Sayan

0
我成功地获得了我想要的东西。我的HTTP POST请求字符串如下所示:
"POST %s HTTP/1.0\r\n" 
"Host: %s\r\n"
"Content-type: multipart/form-data\r\n"
"Content-length: %d\r\n\r\n"
"Content-Disposition: %s; filename: %s\n"

我正在从客户端的cpp程序向运行Apache的服务器发送上述字符串,该服务器通过一个也是用cpp编写的cgi脚本处理数据。数据被放置在Content Disposition属性中。请问有人能指出如何将上述内容转换为HTTP PUT吗?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接