【问题标题】:Weird tcpclient https post response奇怪的 tcpclient https 回复
【发布时间】:2011-08-27 18:11:33
【问题描述】:

我在尝试使用 TcpClient 从网页获得完整响应时遇到了一个奇怪的问题,我将 POST 发送到该网页。代码如下:

byte[] RecvBufferxxxx = new byte[4096];

var returnData = "";
var uri = new Uri(string.Format(core.serverAuth, "app_data"));
var head = new WebHeaderCollection();
head[HttpRequestHeader.Host] = uri.Host;
head[HttpRequestHeader.Connection] = "keep-alive";
head[HttpRequestHeader.AcceptEncoding] = "deflate";

using (var client = new TcpClient(uri.Host, 443))
{
    client.SendTimeout = 10000;
    client.ReceiveTimeout = 10000;
    using (SslStream s = new SslStream(client.GetStream(), false, 
        IgnoreCertificateErrorHandler, null))
    {
        s.AuthenticateAsClient(uri.Host, null, SslProtocols.Tls, false);

        var hhd = "POST " + uri.PathAndQuery + " HTTP/1.0\r\n" + head;

        var bts = Encoding.ASCII.GetBytes(hhd);
        s.Write(bts, 0, bts.Length);
        s.Flush();
        s.ReadByte();

        var n = s.Read(RecvBufferxxxx, 0, RecvBufferxxxx.Length);
        // var tmp = Encoding.ASCII.GetString(RecvBufferxxxx, 0, n);
        // ANOTHER CALL SAMPLE   
        // n = s.Read(RecvBufferxxxx, 0, RecvBufferxxxx.Length);

        using (MemoryStream ms = new MemoryStream(RecvBufferxxxx, 0, n))
        {
            ms.ReadByte();
            ms.ReadByte();
            using (DeflateStream df = new DeflateStream(ms, 
                CompressionMode.Decompress))
            {
                using (StreamReader rd = new StreamReader(df))
                {
                    returnData = rd.ReadToEnd();
                }
            }
        }
    }
}

此代码有效,但它只获取响应标头,我需要再次调用以获取响应正文,但我不知道为什么。

响应来自我的服务器,而且很短。

在我只使用Socket 之前,它可以在一次调用中获得所有内容,但现在我已将其重写为添加 SSL 和 deflate 的代码。

我在 firefox 中使用 firebug 检查了相同的链接,并且只有一个 get 和完整的响应。

我用wireshark和firebug仔细检查过,使用firebug和这个代码wireshark列表看起来很相似。

我可以使用此代码进行第二次读取,然后我得到响应正文,但随后我在 wireshark 中看到有另一个 ssl 连接,我不想要这个,我想要就像 firefox 一样。

另一个原因是我只是想知道为什么这会导致单桅帆船解决这些问题,有人可以帮助我吗?

【问题讨论】:

  • 你为什么不使用WebClient 类?或者,如果您需要对请求进行更详细的控制,HttpWebRequest 类?两者都处理压缩流、SSL 和 POST 请求的放缩。
  • 这不是我的问题,使用 webclient 或 httpwebrequest 不是答案。再次阅读我的问题。
  • @svick:也许是作业?如果是这样,则应将homework 标记应用于它。
  • @Programista:我确实阅读了您的问题,无需提醒我重新阅读它(我什至对其进行了编辑以使其更好)。评论 is 是一个答案,它只是不是你想要的答案(这让我相信这是作业,应该有 homework 标签应用于它)
  • 我当然不想要这个答案,我正在尝试使用 tcpclient 来实现,如果您只是不知道答案,请不要强迫我更改它,它很快而且代码在表单启动时执行,这就是原因。这不是家庭作业。但即使是,你至少测试过吗?我有。如果您不知道答案,可能您从未使用过 tcpclient 和 ssl,但这是我的问题。 “使用 webclient/webrequest”不是一个答案,每次有人问 tcpclient 时我都会看到这个,“使用其他东西”因为这很难或者前者更容易。然后我会尝试使用反射器来检查。

标签: c# .net ssl response tcpclient


【解决方案1】:

Stream.Read() 可能不会给你整个缓冲区,它允许返回更少。如果你想读取整个流,你必须循环调用它,直到它返回 0。

【讨论】:

  • 缓冲区有足够的空间,响应很短
  • 缓冲区中是否有足够的空间并不重要。你不能假设Read() 会一次性给你所有东西。原因之一是响应可能包含在多个数据包中,您可能希望在最后一个数据包到达之前开始处理。我不太了解 SSL,但您确定另一个 Read() 会创建另一个事务吗?
  • “响应可能在多个数据包中”,但是当我只使用套接字或 httpwebrequest 时,它是在一个调用中,所以...?
  • 不知道,也许你也改变了其他东西,这会有所不同。
  • 不行,你有代码,测试一下,可以是任何https数据源。
【解决方案2】:

好的,找到了解决方案,但不是问题根源,只是在循环中使用ReadByte,不知道为什么Read有问题,使用反射器我能够发现它可能是@987654323的问题@ 内部缓冲,但谁知道呢。

【讨论】:

    猜你喜欢
    • 2017-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多