【问题标题】:Get underlying tcp connection from HttpWebRequest/Response从 HttpWebRequest/Response 获取底层 tcp 连接
【发布时间】:2011-06-02 22:20:58
【问题描述】:

当我连接到比 HttpWebRequest 和 HttpWebResponse 给我的级别更低的网站时,我正在尝试获取有关正在发生的事情的更多信息。我正在使用 C#。

我希望能够查看有关 dns 查找的信息以及建立连接所需的时间(如果建立了新连接)。 HttpWebRequest 和 HttpWebResponse 在比这更高的级别上工作,我想问是否有办法获取底层 TcpClient 对象(或他们使用的任何低级别对象)。

如果不可能,那么有没有办法在不通过 HttpWebRequest 或 HttpWebResponse 的情况下获取和操作 .net 维护的连接列表?

我无法更改我正在开发的应用程序以使用 TcpClient,因为可靠地实现所有 http 内容太耗时。

【问题讨论】:

  • 不确定“TcpClient”,但我确定他们使用“Socket”类,所以请寻找它。此外,当您断点和调试时,您指向对象,甚至可以看到它们的私有成员。这应该会给你一些方向。
  • 我没想过要看看私人会员,谢谢。不幸的是,我找不到太多。我确实看到 ServicePoint 有一个名为 LastDnsResolve 的非公共变量,我假设它保存了最后一次 DNS 解析的时间。我也许可以用它来解决我的一小部分问题。

标签: c# .net httpwebrequest tcpclient


【解决方案1】:

我能告诉你的最好方法是创建一个包含以下信息的 app.config 文件:

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <system.diagnostics>
        <trace autoflush="true" />
            <sources>
                <source name="System.Net" maxdatasize="1024">
                    <listeners>
                        <add name="MyTraceFile"/>
                    </listeners>
                </source>
              <source name="System.Net.Sockets" maxdatasize="1024">
                    <listeners>
                        <add name="MyTraceFile"/>
                    </listeners>
                </source>  
           </sources>


            <sharedListeners>
                <add
                  name="MyTraceFile"
                  type="System.Diagnostics.TextWriterTraceListener"
                  initializeData="System.Net.trace.log"
                />
            </sharedListeners>
            <switches>
                <add name="System.Net" value="Verbose" />
              <add name="System.Net.Sockets" value="Verbose" />
            </switches>
    </system.diagnostics>
</configuration>

这将启用跟踪,并将在您的应用文件夹中踢出一个名为“System.Net.trace.log”的日志文件。您不会获得您正在寻找的所有信息,并且在应用程序运行时不容易使用它,但至少您不需要运行第三方程序。它没有记录太多,但至少有some information

【讨论】:

  • 基于这个想法,您可以编写自己的TraceListener,这将使您能够在运行时跟踪同一进程中的所有日志。
  • 谢谢,这似乎很接近。我已经按照建议编写了一个 TraceListener 并且可以从套接字跟踪中获取一些信息。但是不幸的是,我无法将显示套接字信息的特定跟踪项与与之关联的特定 HttpWebResponse 匹配。
  • 令人沮丧的是,我可以看到 .NET 在幕后使用套接字,但无法访问它们。有没有办法使用跟踪中显示的唯一对象 ID 之一从 .NET 获取对象?
  • 您可以使用Trace.CorrelationManager.ActivityId。这是一个自动包含在跟踪中的每个线程的值。我不认为HttpWebResponse 使用它,所以你必须自己设置它。
  • 我知道这是一个很晚的接受,但我从未设法按计划让它工作。我认为这是最好的建议。我在尝试解析 TraceListener 中的消息时遇到了一些麻烦,并且由于许多线程同时运行,因此无法找到可靠地将有关单个请求的所有信息串在一起的方法。
【解决方案2】:

使用 Wireshark,这是找出所有这些东西的最佳方式。

【讨论】:

  • 我同意。 HttpWebRequest 的重点是抽象/隐藏复杂的部分。易用性的权衡是您必须在较低级别接受一些“魔法”。
  • 我同意。与其对 .net 的内部进行讨论,不如在请求通过网络时对其进行监控。这应该会给你准确的时间来判断一切发生的时间。
  • 我确实使用过wireshark,但我想在.net 中做同样的事情:监控tcp 连接。我的问题可能不清楚,我希望能够在 .net 中反复自动获取此信息,而不仅仅是一次故障排除。除非您建议我使用 WinPcap 或 Wireshark API(存在吗?)。但这将其提升到了另一个层次,如果可能的话,我想避免这种情况。
【解决方案3】:

如果不是 Wireshark,则使用 Fiddler

【讨论】:

  • 我也用 fiddler。但这让我想到,fiddler 是如何获取它的统计信息的呢?它报告 TCP/IP 连接时间并用 C# 编写。它是否使用 TcpClient/Sockets? Fiddler 的功能非常广泛。我会感到内疚,无法拆卸它,看看它是如何完成的,然后使用相同的想法,因为我觉得这是错误的(而且可能是非法的)。
  • Fiddler 是 HTTP 代理 - 所以当 Fiddled 打开浏览器/任何其他 HTTP 客户端时,它会将请求发送到本地代理(Fiddler)并将它们重新发送到实际服务器。结果,它知道有关请求和响应的所有信息,因为它自己发送它们。但这听起来不像您从原始问题中所需要的——您的进程似乎需要 HTTP/TCP 统计信息...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-06
  • 1970-01-01
相关资源
最近更新 更多