1、构造请求消息体并发送给服务端
搜集端与服务端建立好连接后,前者按照HTTP的要求构造消息体发送给服务端。这段实现代码包含在函数int CHttp::Fetch( string strUrl, char **fileBuf, char **fileHeadBuf, char **location, int* nPSock )中。
HttpFetch函数中部分代码参考了http://fetch.sourceforge.net中的int http_fetch(const char *url_tmp, char **fileBuf)函数,但是它不能够返回请求URL的网页头信息,不能确定网页是否已经重定向,所以有针对性地做了改动。另外由于该函数是用C写成的,为了保持原代码的完整,对于URL的解析需要单独作一次,而不是采用前面已经给出的URL类来实现(URL类在TSE的其他部分会经常用到)。
代码实现在文件Http.cpp中。在TSE中消息体的组装中采用HTTP 1.1协议,抓取程序不主动关闭Socket通道,这样当Web服务器支持持续连接,后续该网站的网页请求就可以利用已经建立的Socket通道进行,可以节省时间和网络带宽。如果服务器不支持持续连接,使用已经建立的Socket通道会报错,此时需要重新建立连接。
2、获取网页头信息和体信息
服务端接受搜集端发送的请求消息后,先返回一个HTTP头信息(为方便起见,后面我们称“网页头信息”),其中包含文件类型,大小,最后修改时间等内容;接着是两个“\r\n”,表现为一个空行;然后返回HTTP体信息,其中包含网页的全文内容。获取上述头信息和体信息的实现代码同样包含在函数int CHttp::Fetch( string strUrl, char **fileBuf, char **fileHeadBuf, char **location, int* nPSock )中,在文件Http.cpp中。
网页头信息获取后,进行解析,根据返回码,判断Web服务器是否针对该请求转向,如果转向,应该重新组装消息体发送请求;根据传输类型,网页体的大小,申请内存空间准备接收,如果超出预定接收大小,放弃该网页;根据网页类型,判断是否获取该网页。如果满足获取条件,继续进行网页体信息的获取。
注意网页头信息中给定的网页体大小有可能错误,所以读取网页体信息应该是处在一个循环体中,直到不能读到新的字节为止。因此根据需求增减内存空间,是格外需要注意的地方。在读取网页信息时,存在服务器长时间不响应的情况,为了加快搜集效率,要设定超时机制,超时后放弃该网页。接收的数据如果超出预定接收大小,放弃该网页。

"发送请求和接收数据"的2条 评论
我来说两句!