谷歌浏览器的源码分析 29

分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net

上一次说到通过WinHTTP来接收网络数据,但没有具体介绍怎么样接收,现在就来分析这方面的代码。首先是通过函数WinHttpQueryHeaders来查询HTTP协议头的大小,接着还是通过函数WinHttpQueryHeaders把数据接收到缓冲区里。下面这段代码,就是做这样的事情:<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

#001  int HttpTransactionWinHttp::DidReceiveHeaders() {

#002    session_callback_->set_load_state(LOAD_STATE_IDLE);

#003

第一次调用函数WinHttpQueryHeaders查看接收到协议头的大小。

#004    DWORD size = 0;

#005    if (!WinHttpQueryHeaders(request_handle_,

#006                             WINHTTP_QUERY_RAW_HEADERS,

#007                             WINHTTP_HEADER_NAME_BY_INDEX,

#008                             NULL,

#009                             &size,

#010                             WINHTTP_NO_HEADER_INDEX)) {

#011      DWORD error = GetLastError();

#012      if (error != ERROR_INSUFFICIENT_BUFFER) {

#013        DLOG(ERROR) << "WinHttpQueryHeaders failed: " << GetLastError();

#014        return TranslateLastOSError();

#015      }

#016      // OK, size should tell us how much to allocate...

#017      DCHECK(size > 0);

#018    }

#019

第二次调用函数WinHttpQueryHeaders来接收协议头的数据。

#020    std::wstring raw_headers;

#021

#022    // ‘size‘ is the number of bytes rather than the number of characters.

#023    DCHECK(size % 2 == 0);

#024    if (!WinHttpQueryHeaders(request_handle_,

#025                             WINHTTP_QUERY_RAW_HEADERS,

#026                             WINHTTP_HEADER_NAME_BY_INDEX,

#027                             WriteInto(&raw_headers, size/2 + 1),

#028                             &size,

#029                             WINHTTP_NO_HEADER_INDEX)) {

#030      DLOG(ERROR) << "WinHttpQueryHeaders failed: " << GetLastError();

#031      return TranslateLastOSError();

#032    }

#033

设置回应的一些状态。

#034    response_.response_time = Time::Now();

#035

#036    // From experimentation, it appears that WinHttp translates non-ASCII bytes

#037    // found in the response headers to UTF-16 assuming that they are encoded

#038    // using the default system charset.  We attempt to undo that here.

#039    response_.headers =

#040        new HttpResponseHeaders(base::SysWideToNativeMB(raw_headers));

#041

#042    // WinHTTP truncates a response longer than 2GB.  Perhaps it stores the

#043    // response‘s content length in a signed 32-bit integer.  We fail rather

#044    // than reading a truncated response.

#045    if (response_.headers->GetContentLength() > 0x80000000)

#046      return ERR_FILE_TOO_BIG;

#047

#048    response_.vary_data.Init(*request_, *response_.headers);

#049    PopulateAuthChallenge();

#050

#051    // Unfortunately, WinHttp does not close the connection when a non-keepalive

#052    // response is _not_ followed by the server closing the connection.  So, we

#053    // attempt to hack around this bug.

#054    if (!response_.headers->IsKeepAlive())

#055      content_length_remaining_ = response_.headers->GetContentLength();

#056

#057    return OK;

#058  }

通过上面的函数处理,就可以收到HTTP协议头的数据,这样就可以进一步处理了。那么接着下来就是收到HTTP协议里的数据,这个主要通过下面的函数来接收到的,如下:

#001  BOOL HttpTransactionWinHttp::SessionCallback::ReadData(

#002      HINTERNET request_handle) {

#003    DCHECK(bytes_available_ >= 0);

#004    char* buf = read_buf_;

#005    read_buf_ = NULL;

#006    int bytes_to_read = std::min(bytes_available_, read_buf_len_);

#007    read_buf_len_ = 0;

#008    if (!bytes_to_read)

#009      bytes_to_read = 1;

#010

#011    // Because of how WinHTTP fills memory when used asynchronously, Purify isn‘t

#012    // able to detect that it‘s been initialized, so it scans for 0xcd in the

#013    // buffer and reports UMRs (uninitialized memory reads) for those individual

#014    // bytes. We override that to avoid the false error reports.

#015    // See http://b/issue?id=1173916.

#016    base::MemoryDebug::MarkAsInitialized(buf, bytes_to_read);

#017    return WinHttpReadData(request_handle, buf, bytes_to_read, NULL);

#018  }

上面通过判断可以接收到多少字节,然后通过函数WinHttpReadData把数据保存到缓冲区read_buf_里,在这个缓冲区里保存了所有网络接收到的数据,那么这些数据又将要流向何方呢?下一次再来分析这个问题。

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net

原文地址:https://www.cnblogs.com/skiwnchh/p/10516120.html

时间: 2024-11-06 07:16:27

谷歌浏览器的源码分析 29的相关文章

谷歌浏览器的源码分析 21

分享一下我老师大神的人工智能教程吧.零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net 上一次说到类RenderThread和类RenderView把消息处理,那么这两个类是怎么样处理消息的呢?又是怎么样处理浏览的消息呢?现在就带着这两个问题去分析它的源码,理解它处理消息的方法.类RenderThread处理消息的代码如下:<?xml:namespace prefix = o ns = "urn:schemas-

谷歌浏览器的源码分析 4

关于对话框,主要实现了让用户查看当前软件的版本.软件信息和检查升级的功能.因此这个类主要继续ChromeViews::View类.ChromeViews::DialogDelegate和GoogleUpdateStatusListener.其中ChromeViews::View实现窗口的布局和显示问题,ChromeViews::DialogDelegate实现了事件响应,或者窗口某时是否可以显示按钮的问题,GoogleUpdateStatusListener是用来实现接收更新程序状态信息. 这个

谷歌浏览器的源码分析 6

前面已经介绍了这么引人的输入自动完成功能,并且可以在输入超级连接框里直接通过GOOGLE搜索所有的内容,这是比较大的创新,不但可以节省界面的占用面积,还很方便大家查询的需要,比如记不住的连接,根本不需要去记了,只要你记住需要的内容就行了.这样既不需要到什么门户网站去找连接,也不需要去记住众多的网站,这个功能是非常方便的. 这个输入框的自动完成的功能,是比较智能化的.因为它会根据以往的输入自动完成,或者智能提示所需要的连接或者内容. 下面就来先看这个类的定义: #001  // Provides

谷歌浏览器的源码分析 34

通过上一次的分析,我们看到所有网页数据经过HTML分析器之后,都会变成一个一个RenderObject对象,那么这些RenderObject对象又是怎么样显示到界面上面的呢?现在就带着这个疑问来分析下面的代码,这样肯定会找到解决方法的.怎么样找到入口呢?其实可以先从界面显示的类开始,可以看到显示界面的窗口类名称叫做Chrome_RenderWidgetHostHWND,有了这个类名称,就可以到代码里查看它在那里了. #001  class RenderWidgetHost; #002  clas

谷歌浏览器的源码分析 7

当我们键入字母或者文字开始时,那么类AutocompleteEdit就会从窗口消息里获取到相应的字母或者文字,然后根据输入的信息到本地或者网络上保存的信息库里查找相应的输入提示,这就是自动完成的实现.下面就来先分析输入的函数:<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> #001  void AutocompleteEdit::OnChar(TCHAR ch, UIN

谷歌浏览器的源码分析 9

为了处理字符消息实现自动完成的功能,这是怎么样实现的呢?其实是先记录字符消息响应前的字符串以及选中状态,接着再处理消息,最后才查询可能的输入,做出智能提示.<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> #001  void AutocompleteEdit::OnBeforePossibleChange() { #002    // Record our state.

谷歌浏览器的源码分析 13

分享一下我老师大神的人工智能教程吧.零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net 上一次说到调用函数OpenURL来打开网络连接,这仅是网络浏览的开始,现在再来分析它怎么样去下载网页数据,然后再显示出来.<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> #001  void Autocom

Solr4.8.0源码分析(22)之 SolrCloud的Recovery策略(三)

Solr4.8.0源码分析(22)之 SolrCloud的Recovery策略(三) 本文是SolrCloud的Recovery策略系列的第三篇文章,前面两篇主要介绍了Recovery的总体流程,以及PeerSync策略.本文以及后续的文章将重点介绍Replication策略.Replication策略不但可以在SolrCloud中起到leader到replica的数据同步,也可以在用多个单独的Solr来实现主从同步.本文先介绍在SolrCloud的leader到replica的数据同步,下一篇

【Heritrix源码分析】Heritrix基本内容介绍

1.版本说明 (1)最新版本:3.3.0 (2)最新release版本:3.2.0 (3)重要历史版本:1.14.4 3.1.0及之前的版本:http://sourceforge.net/projects/archive-crawler/files/ 3.2.0及之后的版本:http://archive.org/ 由于国情需要,后者无法访问,因此本blog研究的是1.14.4版本. 2.官方材料 source:http://sourceforge.net/projects/archive-cra