我正在尝试使用C ++创建一个简单的http服务器。我在C ++中遵循beej's guide网络编程。
当我在某个端口(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>
不是一个很大的“Hello,client!..”字符串,就像通常用h1标记的字符串一样。问题是什么?我在标题中遗漏了什么吗?
另一个问题是,为什么服务器不能在端口80中运行?服务器中的错误日志说:
server: bind: Permission denied
server: bind: Permission denied
Server failed to bind
libc++abi.dylib: terminate called throwing an exception
请帮忙。谢谢。编辑:我在端口80上没有任何进程。
答案 0 :(得分: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端口问题,其他一些应用程序可能会绑定它。
答案 1 :(得分:2)
您需要使用\r\n\r\n
终止HTTP响应标头,而不仅仅是\r\n
。它也应该从更像HTTP/1.1 200 OK\r\n
的内容开始,而不是前导\r\n
。
对于您的端口问题,如果您在相关端口上没有运行任何其他内容,您可能会发现上一次运行程序创建的套接字仍然存在。要解决此问题,可以使用setsockopt
在套接字上设置SO_REUSEADDR
标志。 (这不建议用于一般用途,我相信因为您可能会收到不适合您的程序的数据,但是对于开发而言,它非常方便。)
答案 2 :(得分:0)
你需要添加&#34;内容长度:&#34;,长度是你的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>";