我正在使用类似的方法来使用C创建服务器。当我从浏览器转到127.0.0.1:5000
时,可以看到"Hello Worlds"
,因为我将其作为缓冲区发送。但是我要127.0.0.1:5000/filename.html
工作。但是我不知道如何获得C中filename
之后的127.0.0.1:5000
。
我正在使用它进行连接:
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(5000);
bind(listenfd, (struct sockaddr*)&serv_addr,sizeof(serv_addr));
connfd = accept(listenfd, (struct sockaddr*)NULL ,NULL);
浏览器将向您的服务器发送一个HTTP请求,其中包含其后的URL。该请求可能如下所示:
GET /filename.html HTTP/1.1
Host: 127.0.0.1:5000
您的C程序必须从套接字读取此请求,然后parse才能找到URL。请注意,该请求可能包含比上述更多的信息,但该请求应始终以空行结尾(因此您知道在何处停止解析)。 HTTP请求中的行应以回车符和换行符("\r\n"
)结尾。
您通过用于发送数据的同一套接字接收数据。读取HTTP请求的步骤可能是这样的:
声明一个足够大的缓冲区,可能是4096字节或更多。
使用read
和您的read
将数据读入此缓冲区,直到:
您已收到4095字节(在这种情况下,您的服务器应响应,错误413)
您遇到了字符connfd
(表示空白行)
经过一段时间,以上均未发生。为了实现超时,您将需要使用"\r\n\r\n"
或select()
。
一旦您将HTTP请求接收到缓冲区中,就对其进行解析:
第一行是request行,它指示请求的方法,URI和协议版本号。解析此行的一种可能方法是按空格将其拆分。
后续行表示HTTP标头字段,通常可以将其解析为select()
。这些头字段包含cookie,有关发出请求的客户端的信息,等等。
您还需要形成HTTP 响应。 URI指定有效资源(例如poll()
)时的响应可能是:
poll()
以上,Key: Value\r\n
是指filename.html
文件中的字节数。就像请求一样,使用空行将响应与数据分开。
当以正确的状态接收数据时,尝试将其解析为http请求。在解析任何内容之前,请等待CRLF CRLF(指示http头的结尾),
HTTP/1.1 200 OK
Date: Thu, 25 Jul 2013 03:55:00 GMT
Server: sadaf2605-server/1.0
Content-Type: text/html
Content-Length: 40595
< contents of filename.html follows here >
然后您应该在字符串中使用]搜索字符串>
Content-Length
然后
filename.html
就在旁边,执行+1,您会在那找到。
我发现评分最高的答案有助于理解概念上需要做的事情,但是不足以帮助新的C / C ++开发人员理解如何阅读标头。