如何在 C 语言中创建支持 PHP 页面的网络服务器?
How can I create a webserver in C which supports PHP pages?
首先,我知道创建处理静态 html 页面的 Web 服务器。
我想创建一个 支持 PHP 页面的网络服务器。
我编写了如下服务器代码,
-> main()
函数只是创建一个套接字,接受请求并调用 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 */
}
-> connection()
函数设置文档根目录,并显式设置一个 PHP 页面 (echo.php) 并调用 php-cgi() 函数。 php-cgi() 做进一步处理。
其实我不知道php5-cgi 是做什么的。当我运行服务器并从网络浏览器请求页面时,它显示"Am a PHP file" 1秒,然后隐藏,显示消息,
The connection was reset
1) 处理 Web 服务器 php 页面的正确方法是什么
2) 谁能给我推荐一些书或任何东西来用 C 开发一个处理 PHP 页的 Web 服务器?
3) 我想试试其他语言吗?哪种语言是创建 Web 服务器和代理的最佳语言?
4) 如何处理查询字符串和POST方法请求?
当我远程登录到服务器时,它工作正常,
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>
您缺少一些 HTTP header 字段。问题之一是浏览器不知道需要多少数据;因此,当它接收和解析数据时,连接已关闭,因为您的 PHP 脚本结束并且浏览器进入 "Huh?"。
因此,您必须发送 Content-length header(如果您事先知道 body 的长度)或 Transfer-encoding 字段(请参阅 http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2).第一个解决方案增加了另一个问题:您必须在发送 header 之前确定长度。这意味着捕获缓冲区中的所有输出,计算字节数,然后发送 header(s) 后跟内容。但这会在您的代码中添加另一个 fork() ...我尝试添加一个 header 像 Transfer-Encoding: identity
但效果不佳。您可能还想添加 Connection: close
header。
你的其他问题有点笼统;无论您使用哪种语言,您都必须完成解析 HTTP 请求 headers、组装 headers、分叉、解析参数等所有艰苦工作。您使用 fork( ), execl() 在理论上是合理的,但需要做更多的工作。所以,是的,使用 Apache、nginx 或任何其他网络服务器听起来很诱人...
首先,我知道创建处理静态 html 页面的 Web 服务器。
我想创建一个 支持 PHP 页面的网络服务器。
我编写了如下服务器代码,
-> main()
函数只是创建一个套接字,接受请求并调用 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 */
}
-> connection()
函数设置文档根目录,并显式设置一个 PHP 页面 (echo.php) 并调用 php-cgi() 函数。 php-cgi() 做进一步处理。
其实我不知道php5-cgi 是做什么的。当我运行服务器并从网络浏览器请求页面时,它显示"Am a PHP file" 1秒,然后隐藏,显示消息,
The connection was reset
1) 处理 Web 服务器 php 页面的正确方法是什么
2) 谁能给我推荐一些书或任何东西来用 C 开发一个处理 PHP 页的 Web 服务器?
3) 我想试试其他语言吗?哪种语言是创建 Web 服务器和代理的最佳语言?
4) 如何处理查询字符串和POST方法请求?
当我远程登录到服务器时,它工作正常,
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>
您缺少一些 HTTP header 字段。问题之一是浏览器不知道需要多少数据;因此,当它接收和解析数据时,连接已关闭,因为您的 PHP 脚本结束并且浏览器进入 "Huh?"。
因此,您必须发送 Content-length header(如果您事先知道 body 的长度)或 Transfer-encoding 字段(请参阅 http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2).第一个解决方案增加了另一个问题:您必须在发送 header 之前确定长度。这意味着捕获缓冲区中的所有输出,计算字节数,然后发送 header(s) 后跟内容。但这会在您的代码中添加另一个 fork() ...我尝试添加一个 header 像 Transfer-Encoding: identity
但效果不佳。您可能还想添加 Connection: close
header。
你的其他问题有点笼统;无论您使用哪种语言,您都必须完成解析 HTTP 请求 headers、组装 headers、分叉、解析参数等所有艰苦工作。您使用 fork( ), execl() 在理论上是合理的,但需要做更多的工作。所以,是的,使用 Apache、nginx 或任何其他网络服务器听起来很诱人...