知道何时停止从HTTP级别的.NET套接字读取

时间:2011-02-24 19:02:36

标签: .net sockets

.NET Socket和NetworkStream都提供Read方法,当没有可用数据时,它会阻塞。问题是,如果客户端不知道消息的大小,就没有可靠的方法来理解服务器何时完成发送消息。

我的问题是 - 更高级别的库(如HTTP级WebRequest)使用什么原则来停止从套接字读取并向客户端显示完整的消息,而不诉诸任何类型的读取超时?似乎HTTP协议不提供任何“EOF”令牌......

3 个答案:

答案 0 :(得分:3)

HTTP 1.1通过使用两种机制之一来管理它。要么在标头中发送content-length,要么使用chunked transfer encoding。分块转码编码是HTTP 1.1优于HTTP 1.0的一大优势,其中,在没有发送内容长度的情况下,无法可靠地检测到传输结束,导致传输问题与有效载荷的实际结束之间存在歧义。在某些情况下(例如HTTP上的音频流),没有内容长度或其他编码可能表明传输结束,但在这种情况下,它对客户端来说并不重要。

答案 1 :(得分:1)

有一些方法可以检查套接字是否有数据待处理。一种是简单地检查每个套接字的Pending属性,只有在有数据时才调用Receive。但是,这根本不能很好地扩展,我只建议在单个连接的应用程序中使用它。

Socket.Select函数可以使用套接字的IList,并且在短时间之后,将减少此列表以仅包含具有待处理数据的套接字。然后,您可以安全地呼叫接收,而不会阻止。

另一种首选方法是使用异步套接字API。 (在NetworkStream上呼叫BeginReceiveBeginRead)。在这些情况下,调用不会阻塞,您可以在调用后继续执行代码。您将函数作为参数传递,该参数将在套接字上的数据挂起时执行。这是在.NET threadpool中的后台线程中处理的,因此这里涉及并发问题,与前两种方法不同。异步操作在OS中的低级别完成,通过使用中断告诉CPU何时数据在网络上等待,而不是像Select一样重复轮询数据。

答案 2 :(得分:0)

在HTTP中,content-length HTTP标头定义何时可以关闭套接字。

在TCP中,这是任意的,通常客户端或服务器发送一条特殊消息来通知该连接正在终止。