热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

网络编程中如何得知一次请求(或响应)的数据已接收完

两年前用.net2.0做了一个反向代理服务器,在这两年时间里,不断修改BUG以及优化性能,使得可用性大大提高。近来碰到一个功能需求,实在无法找出有效的解决办法,只好上来请教各位高人。
    两年前用.net 2.0做了一个反向代理服务器,在这两年时间里,不断修改BUG以及优化性能,使得可用性大大提高。近来碰到一个功能需求,实在无法找出有效的解决办法,只好上来请教各位高人。
    先说说反向代理的工作机理吧。
1、客户端通过浏览器访问反向代理的时候,会发出一个HTTP请求,反向代理收到这个TCP连接的时候,建立一个新的会话用于处理这个请求(BeginAccept、EndAccept);
2、会话对象建立一个从客户端接收数据的委托,开始异步读取数据(BeginRead);
3、取得数据时,进入异步读取的回调函数中,开始处理数据(EndRead);
4、检查反向代理与服务器的连接是否已建立,如果没有建立,那么需要先建立连接(ConnectServer),并建立服务器的异步读取委托(BeginRead);
5、把数据异步写入服务器(BeginWrite);
6、重新建立客户端异步读取委托(BeginRead),回到3;
7、收到服务器返回数据时,处理后,异步写入客户端(BeginWrite);
8、重新建立服务器异步读取委托(BeginRead),回到7;

所有的数据传输,都使用异步来完成,而只需要在3和7处为业务编写数据处理代码即可。
实际上,对于反向代理来说,只需要处理客户端发来的数据就可以了,需要把HTTP的HOST头替换为真实服务器,而对于服务器响应的数据,只需要原样发送给客户端就可以了。

在步骤3中,我们只知道当前收到了客户端发来的数据,而不知道这个数据是不是Http请求头,或者是完整的Http请求头。幸好,对于反向代理来说,不需要关心是否是完整的Http请求头,只需要检查是否是Http请求头,如果是,就修改Host即可。在这里,我假设Http请求的第一个数据包肯定是独立的数据包,不会“粘”在TCP连接中上一次数据的后面,这样就可以直接使用Http协议规定的格式来检查这个数据包是否Http请求头了。虽然这个假设没有什么依据,但它确实非常有效。

程序就这样工作了两年,没有什么问题。

但接下来,问题就出现了,有一个需求,要求能够把服务器返回的页面中的某个字符串替换为指定的字符串。比如我用反向代理指向博客园,我就需要把博客园页面中所有使用了绝对路径的连接修改为指向反向代理服务器的连接。这就要求在步骤7这里处理数据,把数据转为字符串,然后替换链接,然后才发往客户端。

但步骤7每次收到的数据只是一个片段,而不是整个页面的HTML。即使我们再次假设Http响应的第一个数据包是独立的数据包,也只能识别哪些是响应头,哪些是数据体而已。也想过每一段数据转为这一段的字符串进行处理,但是,如果刚好某个字符被网络层拆分到两个TCP数据包里怎么办?还有,想博客园这样使用了gzip的,如果不接受完整个页面的数据,是无法解压的;就算这两种情况都不存在,而网络层刚好在超链接的地方拆分数据包怎么办?

因此,最保守的做法就是拿到整个页面数据再开始处理。也想过Http响应头那里有个Content-Length指明内容长度的,但实际中,很多响应根本就不到这个段。

我查看过HttpListener类和HttpListenerRequest类,尝试从中发现它是如何接受完一次请求(响应)的,可惜这两个类调用了大量NativeAPI,就无法得知了。

还有浏览器,它又是如何得知某次响应是否已经完成的呢?

还请各位高人多多指教!

这个代理已经放到codeplex上,大家有兴趣可以看看: http://www.codeplex.com/XProxy/

还有,不要忘了给我的问题提个解决思路^_^
谢谢!

QQ:99363590
E-Mail:nnhy#vip.qq.com
QQ群: 10193406
推荐阅读
  • 本文介绍了计算机网络的定义和通信流程,包括客户端编译文件、二进制转换、三层路由设备等。同时,还介绍了计算机网络中常用的关键词,如MAC地址和IP地址。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文介绍了使用PHP实现断点续传乱序合并文件的方法和源码。由于网络原因,文件需要分割成多个部分发送,因此无法按顺序接收。文章中提供了merge2.php的源码,通过使用shuffle函数打乱文件读取顺序,实现了乱序合并文件的功能。同时,还介绍了filesize、glob、unlink、fopen等相关函数的使用。阅读本文可以了解如何使用PHP实现断点续传乱序合并文件的具体步骤。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • Python瓦片图下载、合并、绘图、标记的代码示例
    本文提供了Python瓦片图下载、合并、绘图、标记的代码示例,包括下载代码、多线程下载、图像处理等功能。通过参考geoserver,使用PIL、cv2、numpy、gdal、osr等库实现了瓦片图的下载、合并、绘图和标记功能。代码示例详细介绍了各个功能的实现方法,供读者参考使用。 ... [详细]
  • 利用Visual Basic开发SAP接口程序初探的方法与原理
    本文介绍了利用Visual Basic开发SAP接口程序的方法与原理,以及SAP R/3系统的特点和二次开发平台ABAP的使用。通过程序接口自动读取SAP R/3的数据表或视图,在外部进行处理和利用水晶报表等工具生成符合中国人习惯的报表样式。具体介绍了RFC调用的原理和模型,并强调本文主要不讨论SAP R/3函数的开发,而是针对使用SAP的公司的非ABAP开发人员提供了初步的接口程序开发指导。 ... [详细]
  • 本文介绍了在mac环境下使用nginx配置nodejs代理服务器的步骤,包括安装nginx、创建目录和文件、配置代理的域名和日志记录等。 ... [详细]
  • ASP.NET2.0数据教程之十四:使用FormView的模板
    本文介绍了在ASP.NET 2.0中使用FormView控件来实现自定义的显示外观,与GridView和DetailsView不同,FormView使用模板来呈现,可以实现不规则的外观呈现。同时还介绍了TemplateField的用法和FormView与DetailsView的区别。 ... [详细]
  • WebSocket与Socket.io的理解
    WebSocketprotocol是HTML5一种新的协议。它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 本文介绍了通过ABAP开发往外网发邮件的需求,并提供了配置和代码整理的资料。其中包括了配置SAP邮件服务器的步骤和ABAP写发送邮件代码的过程。通过RZ10配置参数和icm/server_port_1的设定,可以实现向Sap User和外部邮件发送邮件的功能。希望对需要的开发人员有帮助。摘要长度:184字。 ... [详细]
  • 本文介绍了在使用Python中的aiohttp模块模拟服务器时出现的连接失败问题,并提供了相应的解决方法。文章中详细说明了出错的代码以及相关的软件版本和环境信息,同时也提到了相关的警告信息和函数的替代方案。通过阅读本文,读者可以了解到如何解决Python连接服务器失败的问题,并对aiohttp模块有更深入的了解。 ... [详细]
  • 本文介绍了在Windows环境下如何配置php+apache环境,包括下载php7和apache2.4、安装vc2015运行时环境、启动php7和apache2.4等步骤。希望对需要搭建php7环境的读者有一定的参考价值。摘要长度为169字。 ... [详细]
author-avatar
手机用户2502937497
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有