【问题标题】:use TcpClient to send request to server使用 TcpClient 向服务器发送请求
【发布时间】:2012-08-24 15:11:36
【问题描述】:

我问这个问题主要是因为我没有清楚的想法。我相信我了解网络服务器的工作原理,但由于某种原因,我得到的结果与预期不同。

所以基本上我想用代码复制我在真正的网络浏览器上所做的事情。

我有一个名为 Fiddler 的程序,它充当代理,以查看来自 Web 服务器的所有请求和响应。

1.所以当我打开我的兄弟然后转到http://10.10.10.28/tfs:8080 时,就会出现这样的结果:

--------

。 . . .这就是提琴手记录的内容:

当我单击取消或尝试登录时,将发出其他请求,fiddler 将记录更多数据。我不在乎这个权利,我只对模拟第一个请求感兴趣。

无论如何,提琴手告诉我们标题是:

GET http://10.10.10.28/tfs:8080 HTTP/1.1
Host: 10.10.10.28
Connection: keep-alive
Cache-Control: max-age=0
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.83 Safari/537.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

得到的回应是:

HTTP/1.1 401 Unauthorized
Server: Microsoft-IIS/7.5
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
X-Powered-By: ASP.NET
MicrosoftSharePointTeamServices: 12.0.0.6421
Date: Fri, 24 Aug 2012 14:36:22 GMT
Content-Length: 0
Proxy-Support: Session-Based-Authentication

2。终于到了代码的有趣部分 现在我想发送相同的标头并期望得到相同的响应。 由于某种原因,我得到了不同的响应!

public static void Main(string[] args)
{
    // I save the header bytes recorded from fiddler on a file to make sure I am sending the exact same request
    byte[] header = System.IO.File.ReadAllBytes(@"C:\Users\Antonio\Desktop\header");

    // create the client
    TcpClient client = new TcpClient("10.10.10.28", 8080);

    // get the stream so that we can read and write to it
    var stream = client.GetStream();

    // now that we have the stream wait for the server to respond
    WaitForResponse(stream); // waits on a separate thread

    // send the request to the header
    stream.Write(header, 0, header.Length);

    // wait
    Console.Read();
}

public static void WaitForResponse(NetworkStream stream)
{
    Task.Factory.StartNew(() => {
        byte[] buffer = new byte[16384];
        int responseLength = stream.Read(buffer, 0, buffer.Length);
        string resp = System.Text.UTF8Encoding.UTF8.GetString(buffer, 0, responseLength);
        resp = resp; // place breakpoint
    });
    System.Threading.Thread.Sleep(10); // make sure task starts
}

这是我得到的回复:

为什么我得到不同的响应?我相信网络服务器使用 tcp 连接将页面发送到客户端。为什么我采用的这种方法不起作用?另外当我从代码向网络服务器发送请求时,为什么提琴手没有记录任何内容? Google chrome 如何连接到网络服务器?我敢打赌,chrome 浏览器也正在与 Web 服务器建立 tcp 连接。

【问题讨论】:

  • 您似乎想指定一个端口,因为您的 URL 包含:8080。如果是这种情况,则说明您使用了错误的语法。使用http://10.10.10.28:8080/tfs 连接到端口8080,而不是http://10.10.10.28/tfs:8080

标签: c# http webserver tcpclient


【解决方案1】:

在您的示例中,您连接到端口 8080 并请求 URL http://10.10.10.28/tfs:8080。所以你连接到端口 8080,然后从端口 80 请求一些东西。这会导致 Bad Request 的响应。

【讨论】:

    【解决方案2】:

    您正在连接到不同的服务器(端口 8080 与端口 80)。

    另外,来自提琴手的请求看起来不正确。 GET 没有指定方法或主机名。也许这些数据已经过处理以使其看起来更友好?

    我希望请求的第一行看起来更像GET /tfs:8080 HTTP/1.1

    【讨论】:

    • 对代理的请求通常包含完整的 URL,如示例中所示。对普通网站的请求可能包含完整的 URL。
    • 是的,这就是我将标题保存到文件的原因。你是对的,它们有点不同
    【解决方案3】:

    你试图在没有先写请求的情况下读取流,这就是问题所在。

    为什么不用 HttpWebRequest 而不是 TcpClient?

    【讨论】:

    • 我认为使用 TcpClient 而不是 HttpWebRequest 是家庭作业的一部分。
    • 我放置了家庭作业,因为我问了这个问题来学习。我不知道为什么这不起作用!
    • 对,好的。但是,您仍然在读取流而不发送请求(因此在这种情况下您的请求是未知的)
    猜你喜欢
    • 2012-01-03
    • 1970-01-01
    • 2012-12-20
    • 1970-01-01
    • 1970-01-01
    • 2020-04-18
    • 2012-08-20
    • 2018-08-28
    • 2019-03-16
    相关资源
    最近更新 更多