2012-08-24 65 views
1

我在問這個問題主要是因爲我沒有一些清晰的想法。我相信我瞭解Web服務器的工作原理,但出於某種原因,我得到的結果與預期不同。使用TcpClient發送請求到服務器

所以基本上我想用代碼複製我用真正的Web瀏覽器做的事情。

我有一個名爲Fiddler的程序,充當代理以查看來自Web服務器的所有請求和響應。

1.所以,當我打開我的broser和,則跳轉http://10.10.10.28/tfs:8080這是顯示的內容:

-------- enter image description here

。 。 。 。而這也正是小提琴手記錄:

enter image description here

當我點擊取消或嘗試登錄其他請求都將被製成,提琴手會記錄更多的數據。我不在乎這一點,知道我只是在模擬這個第一個請求感興趣。

不管怎麼說所以提琴手運輸發射車我們,標題是:

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 
} 

這裏的響應,我得到: enter image description here

爲什麼會出現不同的反應?我相信Web服務器使用tcp連接將頁面發送到客戶端。爲什麼我採取的這種方法不起作用?另外爲什麼當我從代碼發送請求到網絡服務器時,提琴手不記錄任何東西? Google Chrome如何連接到Web服務器?我敢打賭,Chrome瀏覽器正在建立一個與Web服務器的tcp連接。

+3

看起來你想指定一個端口,因爲你的URL包含:8080。如果是這種情況,那麼您使用的語法錯誤。使用'http://10.10.10.28:8080/tfs'連接到端口8080,而不是'http://10.10.10.28/tfs:8080'。 – Sjoerd

+0

謝謝!這使它工作! –

回答

1

在你的榜樣,您連接到端口8080,並請求URL http://10.10.10.28/tfs:8080。所以你連接到端口8080,然後從端口80請求一些東西。這導致Bad Request的響應。

1

您正在連接到不同的服務器(端口8080 vs端口80)。

此外,來自fiddler的請求看起來不正確。 GET不指定方法或主機名。也許這個數據已經被按摩,使它看起來更友好?

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

+0

對代理的請求通常包含完整的URL,如示例中所示。對普通網站的請求*可能包含完整的網址。 – Sjoerd

+0

是的,這就是爲什麼我將標題保存到文件。你是對的他們有點不同 –

0

您試圖在不先寫入請求的情況下閱讀流,這就是問題所在。

爲什麼不使用HttpWebRequest而不是TcpClient?

+0

我認爲使用TcpClient而不是HttpWebRequest是家庭作業的一部分。 – Sjoerd

+0

我把家庭作業的任務,因爲我問這個問題學習。我無法弄清楚爲什麼這不起作用! –

+0

對,沒關係。但仍然是,您正在閱讀流而不發送請求(因此您的請求在這種情況下是未知的) –