1

我正在尝试用 C++ 制作一个简单的 http 服务器。我遵循了beej 的C++ 网络编程指南。

当我在某个端口(8080、2127 等)中运行服务器时,它通过地址栏访问时成功地向浏览器(Firefox)发送响应:localhost:PORT_NUMBER,端口 80 除外。

这是我写的代码:

printf("Server: Got connection from %s\n", this->client_ip);

if(!fork()) // This is the child process, fork() -> Copy and run process
{
    close(this->server_socket); // Child doesn't need listener socket

    // Try to send message to client
    char message[] = "\r\nHTTP/1.1 \r\nContent-Type: text/html; charset=ISO-8859-4 \r\n<h1>Hello, client! Welcome to the Virtual Machine Web..</h1>";
    int length = strlen(message); // Plus 1 for  null terminator
    int send_res = send(this->connection, message, length, 0); // Flag = 0

    if(send_res == -1)
    {
        perror("send");
    }

    close(this->connection);

    exit(0);
}

close(this->connection); // Parent doesn't need this;

问题是,即使我在响应字符串的早期添加了标题,为什么浏览器没有正确显示 HTML 而只显示纯文本?它显示了这样的内容:

Content-Type: text/html; charset=ISO-8859-4

<h1>Hello, client! Welcome to the Virtual Machine Web..</h1>

不像通常带有 h1 标记的字符串那样大的“你好,客户!..”字符串。问题是什么?我在标题中遗漏了什么吗?

另一个问题是,为什么服务器不会在 80 端口运行?服务器中的错误日志说:

server: bind: Permission denied
server: bind: Permission denied
Server failed to bind
libc++abi.dylib: terminate called throwing an exception

请帮忙。谢谢你。编辑:我在 80 端口上没有任何进程。

4

3 回答 3

3

您需要使用 终止 HTTP 响应标头\r\n\r\n,而不仅仅是\r\n. 它也应该以类似的东西开头HTTP/1.1 200 OK\r\n,没有前导\r\n

对于您的端口问题,如果您在相关端口上没有运行其他任何东西,您可能会发现上次运行程序创建的套接字仍然存在。要解决此问题,您可以使用在套接字上setsockopt设置SO_REUSEADDR标志。(这不推荐用于一般用途,我相信因为您可能会收到不适合您的程序的数据,但对于开发来说它非常方便。)

于 2012-11-22T01:21:39.690 回答
3

您的请求从不应该的\r\n时候开始,它也没有指定状态代码,并且在所有标题之后都需要一个空行。

char message[] = "HTTP/1.1 200 Okay\r\nContent-Type: text/html; charset=ISO-8859-4 \r\n\r\n<h1>Hello, client! Welcome to the Virtual Machine Web..</h1>";

至于您的端口 80 问题,可能会绑定其他一些应用程序。

于 2012-11-22T01:22:08.457 回答
0

你需要添加“Content-length:”,长度就是你的HTML代码,就像这样:

char msg[] = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-length: 20\r\n\r\n<h1>Hello World</h1>";
于 2017-11-03T01:33:21.787 回答