1

私がこの質問をしている主な理由は、いくつかのアイデアがはっきりしていないからです。Web サーバーの仕組みは理解していると思いますが、何らかの理由で予想とは異なる結果が得られます。

つまり、基本的には、コードを使用して実際の Web ブラウザーで行っていることを再現したいと考えています。

Web サーバーからのすべての要求と応答を確認するために、プロキシとして機能する Fiddler というプログラムがあります。

1. ブラウザを開いて goto すると、次のhttp://10.10.10.28/tfs:8080ように表示されます。

--------ここに画像の説明を入力

. . . . そして、これはフィドラーが記録するものです:

ここに画像の説明を入力

キャンセルをクリックするか、ログインを試みると、他のリクエストが行われ、フィドラーはより多くのデータを記録します。この最初のリクエストをシミュレートすることに興味があるだけなので、それは気にしません。

とにかく、フィドラーはヘッダーが次のようであると私たちに伝えています:

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
}

ここに私が得る応答があります: ここに画像の説明を入力

なぜ私は別の応答を得ているのですか? Web サーバーは tcp 接続を使用してページをクライアントに送信すると思います。私が取っているこのアプローチがうまくいかないのはなぜですか?また、コードから Web サーバーにリクエストを送信したときに、フィドラーが何も記録しないのはなぜですか? Google chrome はどのように Web サーバーに接続しますか? Chrome ブラウザーは、Web サーバーとの TCP 接続も確立していると思います。

4

3 に答える 3

1

別のサーバーに接続しています (ポート 8080 対ポート 80)。

また、フィドラーからのリクエストは正しくないようです。GET はメソッドまたはホスト名を指定しません。おそらく、このデータはより友好的に見えるようにマッサージされているのでしょうか?

リクエストの最初の行はもっと似ていると思いますGET /tfs:8080 HTTP/1.1

于 2012-08-24T15:21:07.250 に答える
1

この例では、ポート 8080 に接続し、 URL をリクエストしますhttp://10.10.10.28/tfs:8080。したがって、ポート 8080 に接続し、ポート 80 から何かを要求します。これにより、Bad Request.

于 2012-08-24T15:21:40.603 に答える
0

最初にリクエストを書き込まずにストリームを読み取ろうとしており、それが問題です。

TcpClient の代わりに HttpWebRequest を使用しないのはなぜですか?

于 2012-08-24T15:21:43.070 に答える