C++ 网络编程
什么是 CGI?
-
通用网关接口 (CGI) 是一组标准,用于定义 Web 服务器和自定义脚本之间的信息交换方式。
-
CGI 规范目前由 NCSA 维护,NCSA 定义 CGI 如下 -
-
通用网关接口,即 CGI,是外部网关程序与 HTTP 服务器等信息服务器接口的标准。
-
当前版本是CGI/1.1,CGI/1.2正在开发中。
网页浏览
为了理解 CGI 的概念,让我们看看当我们点击一个超链接来浏览一个特定的网页或 URL 时会发生什么。
-
您的浏览器联系 HTTP Web 服务器并请求 URL,即。文件名。
-
Web 服务器将解析 URL 并查找文件名。如果找到请求的文件,则 Web 服务器将该文件发送回浏览器,否则会发送一条错误消息,表明您请求了错误的文件。
-
Web 浏览器从 Web 服务器获取响应,并根据收到的响应显示接收到的文件或错误消息。
但是,可以将 HTTP 服务器设置为,无论何时请求某个目录中的文件,该文件都不会被发回;而是作为程序执行,并将程序产生的输出发送回您的浏览器进行显示。
通用网关接口 (CGI) 是一种标准协议,用于使应用程序(称为 CGI 程序或 CGI 脚本)能够与 Web 服务器和客户端进行交互。这些 CGI 程序可以用 Python、PERL、Shell、C 或 C++ 等编写。
CGI 架构图
下面的简单程序展示了 CGI 的简单架构 -
网络服务器配置
在继续进行 CGI 编程之前,请确保您的 Web 服务器支持 CGI 并且已配置为处理 CGI 程序。 HTTP 服务器要执行的所有 CGI 程序都保存在预先配置的目录中。这个目录被称为 CGI 目录,按照惯例,它被命名为 /var/www/cgi-bin。按照惯例,CGI 文件的扩展名为 .cgi ,尽管它们是 C++ 可执行文件。
默认情况下,Apache Web 服务器配置为在 /var/www/cgi-bin 中运行 CGI 程序。如果您想指定任何其他目录来运行您的 CGI 脚本,您可以修改 httpd.conf 文件中的以下部分 -
<Directory "/var/www/cgi-bin"> AllowOverride None Options ExecCGI Order allow,deny Allow from all </Directory> <Directory "/var/www/cgi-bin"> Options All </Directory>
在这里,我假设您已经成功启动并运行了 Web 服务器,并且您可以运行任何其他 CGI 程序,例如 Perl 或 Shell 等。
第一个 CGI 程序
考虑以下 C++ 程序内容 -
#include <iostream> using namespace std; int main () { cout << "Content-type:text/html\r\n\r\n"; cout << "<html>\n"; cout << "<head>\n"; cout << "<title>Hello World - First CGI Program</title>\n"; cout << "</head>\n"; cout << "<body>\n"; cout << "<h2>Hello World! This is my first CGI program</h2>\n"; cout << "</body>\n"; cout << "</html>\n"; return 0; }
编译以上代码并将可执行文件命名为 cplusplus.cgi。该文件保存在 /var/www/cgi-bin 目录中,并包含以下内容。在运行您的 CGI 程序之前,请确保您已使用 chmod 755 cplusplus.cgi 更改文件模式 使文件可执行的 UNIX 命令。
我的第一个 CGI 程序
上面的 C++ 程序是一个简单的程序,它将其输出写入 STDOUT 文件,即屏幕。有一个重要且额外的功能可用,即第一行打印 Content-type:text/html\r\n\r\n .此行被发送回浏览器并指定要在浏览器屏幕上显示的内容类型。现在您一定已经了解了 CGI 的基本概念,并且可以使用 Python 编写许多复杂的 CGI 程序。 C++ CGI 程序可以与任何其他外部系统(例如 RDBMS)交互以交换信息。
HTTP 标头
Content-type:text/html\r\n\r\n 行 是 HTTP 标头的一部分,它被发送到浏览器以了解内容。所有 HTTP 标头都将采用以下形式 -
HTTP Field Name: Field Content For Example Content-type: text/html\r\n\r\n
还有一些其他重要的 HTTP 标头,您将在 CGI 编程中经常使用它们。
Sr.No | 页眉和说明 |
---|---|
1 | 内容类型: 定义返回文件格式的 MIME 字符串。示例是 Content-type:text/html。 |
2 | 过期:日期 信息失效的日期。浏览器应该使用它来决定何时需要刷新页面。有效日期字符串的格式应为 01 Jan 1998 12:00:00 GMT。 |
3 | 位置:网址 应返回的 URL,而不是请求的 URL。您可以使用此文件将请求重定向到任何文件。 |
4 | 最后修改时间:日期 资源的最后修改日期。 |
5 | 内容长度:N 返回的数据的长度(以字节为单位)。浏览器使用此值报告文件的估计下载时间。 |
6 | 设置 Cookie:字符串 设置通过字符串传递的cookie . |
CGI 环境变量
所有 CGI 程序都可以访问以下环境变量。这些变量在编写任何 CGI 程序时都起着重要作用。
Sr.No | 变量名和描述 |
---|---|
1 | CONTENT_TYPE 内容的数据类型,在客户端向服务器发送附加内容时使用。比如文件上传等。 |
2 | CONTENT_LENGTH 仅对 POST 请求可用的查询信息的长度。 |
3 | HTTP_COOKIE 以键值对的形式返回设置好的cookies。 |
4 | HTTP_USER_AGENT User-Agent request-header 字段包含有关发起请求的用户代理的信息。它是网络浏览器的名称。 |
5 | PATH_INFO CGI 脚本的路径。 |
6 | QUERY_STRING 使用 GET 方法请求发送的 URL 编码信息。 |
7 | REMOTE_ADDR 发出请求的远程主机的 IP 地址。这对于日志记录或身份验证很有用。 |
8 | REMOTE_HOST 发出请求的主机的完全限定名称。如果此信息不可用,则可以使用 REMOTE_ADDR 获取 IR 地址。 |
9 | REQUEST_METHOD 用于发出请求的方法。最常用的方法是 GET 和 POST。 |
10 | SCRIPT_FILENAME CGI 脚本的完整路径。 |
11 | SCRIPT_NAME CGI 脚本的名称。 |
12 | SERVER_NAME 服务器的主机名或 IP 地址。 |
13 | SERVER_SOFTWARE 服务器正在运行的软件的名称和版本。 |
这是列出所有 CGI 变量的小型 CGI 程序。
#include <iostream> #include <stdlib.h> using namespace std; const string ENV[ 24 ] = { "COMSPEC", "DOCUMENT_ROOT", "GATEWAY_INTERFACE", "HTTP_ACCEPT", "HTTP_ACCEPT_ENCODING", "HTTP_ACCEPT_LANGUAGE", "HTTP_CONNECTION", "HTTP_HOST", "HTTP_USER_AGENT", "PATH", "QUERY_STRING", "REMOTE_ADDR", "REMOTE_PORT", "REQUEST_METHOD", "REQUEST_URI", "SCRIPT_FILENAME", "SCRIPT_NAME", "SERVER_ADDR", "SERVER_ADMIN", "SERVER_NAME","SERVER_PORT","SERVER_PROTOCOL", "SERVER_SIGNATURE","SERVER_SOFTWARE" }; int main () { cout << "Content-type:text/html\r\n\r\n"; cout << "<html>\n"; cout << "<head>\n"; cout << "<title>CGI Environment Variables</title>\n"; cout << "</head>\n"; cout << "<body>\n"; cout << "<table border = \"0\" cellspacing = \"2\">"; for ( int i = 0; i < 24; i++ ) { cout << "<tr><td>" << ENV[ i ] << "</td><td>"; // attempt to retrieve value of environment variable char *value = getenv( ENV[ i ].c_str() ); if ( value != 0 ) { cout << value; } else { cout << "Environment variable does not exist."; } cout << "</td></tr>\n"; } cout << "</table><\n"; cout << "</body>\n"; cout << "</html>\n"; return 0; }
C++ CGI 库
对于实际示例,您需要通过 CGI 程序执行许多操作。有一个为 C++ 程序编写的 CGI 库,您可以从 ftp://ftp.gnu.org/gnu/cgicc/ 下载并按照步骤安装该库 -
$tar xzf cgicc-X.X.X.tar.gz $cd cgicc-X.X.X/ $./configure --prefix=/usr $make $make install
您可以在‘C++ CGI Lib 文档中查看相关文档。
GET 和 POST 方法
当您需要将一些信息从浏览器传递到 Web 服务器并最终传递到 CGI 程序时,您一定遇到过很多情况。最常见的浏览器使用两种方法将此信息传递给 Web 服务器。这些方法是 GET 方法和 POST 方法。
使用 GET 方法传递信息
GET 方法发送附加到页面请求的编码用户信息。页面和编码信息由 ? 分隔。字符如下-
http://www.test.com/cgi-bin/cpp.cgi?key1=value1&key2=value2
GET 方法是将信息从浏览器传递到 Web 服务器的默认方法,它会生成一个长字符串,该字符串会出现在浏览器的 Location:box 中。如果您有要传递给服务器的密码或其他敏感信息,切勿使用 GET 方法。 GET 方法有大小限制,您可以在请求字符串中传递最多 1024 个字符。
使用 GET 方法时,信息使用 QUERY_STRING http 标头传递,并且可以通过 QUERY_STRING 环境变量在您的 CGI 程序中访问。
您可以通过简单地连接键和值对以及任何 URL 来传递信息,也可以使用 HTML
C语言