2010-01-21 17 views
6

Chciałbym utworzyć własne niestandardowe żądania HTTP. Klasa WebClient jest bardzo fajna, ale automatycznie tworzy żądania HTTP. Myślę, że muszę utworzyć połączenie sieciowe z serwerem sieciowym i przekazać moje dane do tego strumienia, ale nie jestem zaznajomiony z klasami bibliotek, które obsługują tego rodzaju rzeczy.Jak utworzyć żądanie HTTP ręcznie w .Net?

(Context, pracuję nad pewnym kodem dla klasy programowania stron internetowych, które uczę. Chcę, aby moi uczniowie zrozumieć podstawy tego, co dzieje się wewnątrz „czarnej skrzynki” HTTP).

Odpowiedz

17

Aby naprawdę zrozumieć wnętrzności protokołu HTTP można użyć TcpClient Klasa:

using (var client = new TcpClient("www.google.com", 80)) 
{ 
    using (var stream = client.GetStream()) 
    using (var writer = new StreamWriter(stream)) 
    using (var reader = new StreamReader(stream)) 
    { 
     writer.AutoFlush = true; 
     // Send request headers 
     writer.WriteLine("GET/HTTP/1.1"); 
     writer.WriteLine("Host: www.google.com:80"); 
     writer.WriteLine("Connection: close"); 
     writer.WriteLine(); 
     writer.WriteLine(); 

     // Read the response from server 
     Console.WriteLine(reader.ReadToEnd()); 
    } 
} 

Inną możliwością jest activate tracing umieszczając wykonaj następujące czynności w swoim app.config i po prostu użyj WebClient, aby wykonać żądanie HTTP:

<configuration> 
    <system.diagnostics> 
    <sources> 
     <source name="System.Net" tracemode="protocolonly"> 
     <listeners> 
      <add name="System.Net"/> 
     </listeners> 
     </source> 
    </sources> 
    <switches> 
     <add name="System.Net" value="Verbose"/> 
    </switches> 
    <sharedListeners> 
     <add name="System.Net" 
      type="System.Diagnostics.TextWriterTraceListener" 
      initializeData="network.log" /> 
    </sharedListeners> 
    <trace autoflush="true"/> 
    </system.diagnostics> 
</configuration> 

Następnie można wykonywać połączenia HTTP:

using (var client = new WebClient()) 
{ 
    var result = client.DownloadString("http://www.google.com"); 
} 

I wreszcie analizować ruch sieciowy w wygenerowanym network.log pliku. WebClient będzie także śledzić przekierowania HTTP.

+0

Doskonały przykład, czekam na wypróbowanie go. To świetny sposób na wizualizację tego, co się dzieje. Dzięki – Jeff

4

W razie potrzeby użyj klas WebRequest lub WebResponse.

Jeśli potrzebujesz przejść na niższy poziom niż te, sprawdź inne klasy System.Net.Sockets. * Klasy klientów, takie jak TcpClient.

2

Zapoznaj się z System.Net.Sockets.TcpClient, jeśli chcesz napisać własnego klienta niskiego poziomu. W przypadku HTTP GET i POST można używać klas HttpWebRequest i HttpWebResponse.

Jeśli jesteś naprawdę masochistą, możesz zejść niżej niż TcpClient i zaimplementować własny Socket, patrz Socket class.

+0

To jest to. Długa, długa droga do żądania sieci. –

+1

Użycie TcpClient również wymagałoby od niego zrozumienia protokołu TELNET, na którym zbudowany jest Http. –

+1

@John: Jeszcze jeden bonus! –

2

W mojej odpowiedzi na to stanowisko SO SharePoint 2007, how to check if a folder exists in a document library zawierałem podstawy tworzenia HttpWebRequest i odpowiedzi odczytu.

Edit: dodano przykład kodu z postu powyżej

System.Net.HttpWebRequest oReq; 
string sUrl = "http://yoursite/sites/somesite/DocumentLibrary"; 
oReq = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(sUrl); 

oReq.Method = "GET"; 
oReq.Credentials = System.Net.CredentialCache.DefaultCredentials; 
oReq.AllowAutoRedirect = true; 

//now send the request 
using (System.IO.StreamWriter oRequest = 
     new System.IO.StreamWriter(oReq.GetRequestStream())) { 
    oRequest.WriteLine(); 
} 

//and read all the response 
using (System.Net.HttpWebResponse oResponse = oReq.GetResponse()){ 
    using (System.IO.StreamReader oResponseReader = 
     new System.IO.StreamReader(oResponse.GetResponseStream())){ 
    string sResponse = oResponseReader.ReadToEnd(); 
    } 
} 
+0

-1: Brakujące bloki 'using' dla StreamReader/Writer i dla odpowiedzi. –

+1

@John Saunders: Wiem, że "używanie" jest dobrym wzorcem do kodowania, jednak - wywołanie close() na czytniku strumienia ZAMKNIJ zamknięcie strumienia bazowego i "zwolnienie wszelkich zasobów systemowych związanych z czytnikiem" (zobacz dokumentację MSDN). Więc - mylisz się, jeśli myślisz, że coś tu szukam. – naivists

+0

Wyciekacie, jeśli część rzeczy między nimi zgłasza wyjątek. – nos

1

Użyj WFetch do demonstracji.

chodzi o programowanie, HttpWebRequest pozwala kontrolować sporo o zamówienie - ponownie, jeśli to dla demonstracji użyję Wireshark wąchać, co się dzieje nad drutu podczas wykonywania różnych zadań z HttpWebRequest