【问题标题】:How can I create a webserver in C which supports PHP pages?如何在 C 中创建一个支持 PHP 页面的网络服务器?
【发布时间】:2015-03-28 22:54:43
【问题描述】:

首先,我知道要创建处理静态 html 页面的 Web 服务器。

我想创建一个支持 PHP 页面的网络服务器。

我编写了如下所示的服务器, -> main()函数只是创建一个socket,接受一个请求并调用connection(fd)函数。

int main(int argc, char *argv[]) {
     int sockfd, newsockfd, portno, pid;
     socklen_t clilen;
     struct sockaddr_in serv_addr, cli_addr;

     if (argc < 2) {
          fprintf(stderr, "ERROR, no port provided\n");
          exit(1);
     }
     sockfd = socket(AF_INET, SOCK_STREAM, 0);
     if (sockfd < 0)
         error("ERROR opening socket");
     bzero((char *) &serv_addr, sizeof(serv_addr));
     portno = atoi(argv[1]);
     serv_addr.sin_family = AF_INET;
     serv_addr.sin_addr.s_addr = INADDR_ANY;
     serv_addr.sin_port = htons(portno);
     if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
        error("ERROR on binding");
     listen(sockfd, 5);
     clilen = sizeof(cli_addr);
     /*
      Server runs forever, forking off a separate
      process for each connection.
      */
     while (1) {
          newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
          if (newsockfd < 0)
             error("ERROR on accept");
          pid = fork();

          if (pid < 0)
              error("ERROR on fork");
          if (pid == 0) {
               close(sockfd);
               connection(newsockfd);
               exit(0);
          } else
            close(newsockfd);
     } /* end of while */
     close(sockfd);
     return 0; /* we never get here */
}

-&gt; connection() 函数设置文档根目录,并显式设置 PHP 页面(echo.php)并调用 php-cgi() 函数。 php-cgi() 做进一步的处理。

其实我不知道 php5-cgi 是做什么的。当我运行服务器并从 Web 浏览器请求页面时,它会显示“我是 PHP 文件”1 秒钟,然后隐藏、显示消息,

连接已重置

1) 在 web 服务器中处理 php 页面的正确方法是什么

2) 谁能推荐我一些书或任何东西来用 C 语言开发一个处理 PHP 页面的 Web 服务器?

3) 我想尝试其他语言吗?哪种语言最适合创建 Web 服务器和代理?

4)如何处理查询字符串和POST方法请求?

当我对服务器进行 telnet 时,它可以工作,

GET /echo.php HTTP/1.1
HTTP/1.1 200 OK
X-Powered-By: PHP/5.5.9-1ubuntu4.6
Content-type: text/html

<html>
<body>
Am a PHP file
</body>
</html>

【问题讨论】:

  • php 有内置的网络服务器。要运行简单的 Web 服务器,您可以从命令提示符 php -S localhost:80 运行此命令
  • 但是我如何创建像 apache 这样的网络服务器?不想要太多安全性,但它应该执行 PHP 脚本。我怎样才能做到这一点?

标签: php c sockets webserver


【解决方案1】:

您缺少一些 HTTP 标头字段。问题之一是浏览器不知道需要多少数据。因此,当它接收并解析数据时,连接已关闭,因为您的 PHP 脚本结束并且浏览器会“嗯?”。

因此,您必须发送 Content-length 标头(如果您事先知道正文的长度)或 Transfer-encoding 字段(请参阅http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2)。第一个解决方案增加了另一个问题:您必须在发送标头之前确定长度。这意味着捕获缓冲区中的所有输出,计算字节数,然后发送标头,然后发送内容。但这会在您的代码中添加另一个 fork()... 我尝试添加像 Transfer-Encoding: identity 这样的标头,但效果不佳。您可能还想添加一个Connection: close 标头。

您的其他问题有点宽泛;无论您使用哪种语言,您都必须完成解析 HTTP 请求标头、组装标头、分叉、解析参数等所有艰苦的工作。您使用 fork()、execl() 的方法在理论上是合理的,但需要更多的工作。所以,是的,使用 Apache、nginx 或任何其他网络服务器听起来很诱人......

【讨论】:

  • 谢谢。但现在我想知道。 PHP 脚本如何在服务器中执行。这和我使用 ph5-cgi 脚本的方式一样吗?我在哪里可以找到实施该文件的文档?
  • 当我使用 execl("/usr/bin/php5-cgi", "php5-cgi", NULL);它直接与带有 2 个标题的浏览器对话:- X-Powered-By:PHP/5.5.9-1ubuntu4.6 Content-Type:text/html。它不会发送最后一个“\r\n\r\n”来将标头与实体主体分开。我对吗?我该如何添加。我想我很接近了,你能帮帮我吗?
  • 当我远程登录到服务器时,我得到了工作结果,GET /echo.php HTTP/1.1 HTTP/1.1 200 OK X-Powered-By: PHP/5.5.9-1ubuntu4.6 Content -type: text/html 是一个 PHP 文件
  • 我认为没有文档可以准确描述如何调用 php5-cgi 脚本;您可能想查看 PHP Apache 模块的源代码(它们是 PHP 源代码的一部分)。正如您所指出的,php5-cgi 二进制文件已经添加了一些标题行。这使您的工作更加复杂,因为您必须从可执行文件中读取输出,读取标头(可能修改它们),然后开始处理输出的主体,添加您自己的标头,然后发送主体。您实际上可能想尝试使用 popen() 调用而不是 execl()。
  • 我明白了。现在我有一个疑问,要为 GET 请求传递查询字符串,我可以使用“putenv(”QUERY_STRING=");”,所以要传递 POST 请求参数,我需要设置哪个 ENVIRONMENT 变量??
猜你喜欢
  • 2012-07-10
  • 2017-10-10
  • 2013-08-03
  • 2018-05-13
  • 2014-01-30
  • 1970-01-01
  • 2013-10-20
  • 2012-06-01
  • 1970-01-01
相关资源
最近更新 更多