2009-12-01 128 views
2

我在使用.Net TcpClient/Sockets编写HTTP客户端。.Net C#TcpClient/Socket HTTP客户端性能/效率

到目前为止,客户端通过遍历NetworkStream响应(在向TcpClient写入GET请求之后),解析报头并检索相关消息体字节/分块字节来处理Content-Length和分块响应。为此,它使用NetworkStream ReadByte方法。

这一切工作正常,但性能是应用程序的一个关键考虑因素,所以我想尽可能快速和高效。

最初,这将涉及将ReadByte替换为邮件正文(基于Content-Length)的Read或分块邮件正文字节检索到适当大小的缓冲区中,在所有其他区域中使用ReadByte(例如,读取Headers,Chunk大小等等)。

我很想知道更好的/不同的方式来达到最佳性能的想法吗?显然,HTTP的主要问题是不知道响应流的长度,除非它在检索时被解析。

有一个具体的原因,为什么我没有使用更多的抽象类(例如HttpWebRequest)(我需要在套接字级更好的控制)。

非常感谢,

克里斯

+0

顺便说一句我很好奇 - 你提到你需要对Socket/Connection进行细粒度的控制,这就是为什么你不使用HttpWebRequest。你能告诉我们那些原因吗? – feroze 2009-12-02 01:58:06

+0

我想模拟一个数字(可以说200个)Web客户端,并且要做到这一点我希望每个客户端都作为一个线程来管理自己的连接,在多个不同请求期间保持打开状态,暂停等等。客户端将达到相同的终点(与标准负载测试工具非常相似的功能)。 我不相信HttpWebRequest可以实现这一点,因为连接是通过服务点来处理的,该服务点可以停止这种粒度控制级别? – Chris 2009-12-02 11:46:40

+0

对不起,我还应该说我需要捕获的信息,如第一个字节的时间,重新连接数等... – Chris 2009-12-02 12:11:44

回答

1

我建议使用一个进程,一个中等大小的缓冲区。重复填充缓冲区,直到响应流结束。当缓冲区已满或流结束时,将缓冲区内容附加到字符串(或用于存储消息的任何内容)。

如果您想在流的早期读取重要的信息位,请阅读足够的流以查看该信息。 (换句话说,如果你不想要,你不需要在第一遍填充缓冲区。)

你还应该考虑使用事件系统来表示新数据的存在这样你的过程的主要部分就不需要知道数据来自何处或你如何缓冲它。

编辑

在回答您的评论的问题,如果你有一个连接,你尝试多个请求重用,你可以创建一个线程,一遍又一遍从中读取。当它找到数据时,它会使用该事件将它推出以供程序的主要部分处理。我没有一个方便的样本,但你应该能够找到几个与谷歌或谷歌搜索几个。

+0

谢谢约翰。然而,如果我使用缓冲区,我认为我需要使用Read(),它会在超过流结束时阻塞。当最后一个字节被读取以进一步解析响应等时,我需要立即移动? 此外,您是否有任何示例/链接到类似的基于事件的系统? 谢谢! – Chris 2009-12-01 18:35:36

+0

如果您发送“Connection:close”作为请求的一部分,则可以防止阻止。 – 2009-12-01 19:01:26

+0

不幸的是重新使用连接/保持活着也很重要... – Chris 2009-12-01 19:28:36