C#: How to execute a HTTP request using sockets?

前端 未结 4 660
难免孤独
难免孤独 2020-12-06 05:51

I am trying to make a HTTP request using sockets. My code is as follows:

using System;
using System.Net;
using System.Net.Sockets;
using System.         


        
相关标签:
4条回答
  • 2020-12-06 05:56

    You must include content-length and double new line in the end to indicate end of header.

    var request = "GET /register?id=application/vnd-fullphat.test&title=My%20Test%20App HTTP/1.1\r\n" + 
        "Host: 127.0.0.1\r\n" +
        "Content-Length: 0\r\n" +
        "\r\n";
    

    The HTTP 1.1 specification can be found here: http://www.w3.org/Protocols/rfc2616/rfc2616.html

    0 讨论(0)
  • 2020-12-06 06:13

    Your request is not correct. According to wikipedia, a HTTP Get request has to look like:

    string request = "GET /register?id=application/vnd-fullphat.test&title=My%20Test%20App HTTP/1.1\r\nHost: 127.0.0.1\r\n";
    
    0 讨论(0)
  • 2020-12-06 06:13

    The minimum requirement for a HTTP request is "GET / HTTP/1.0\r\n\r\n" (if removing the Host is allowed). But in SNARL, you must input the content-length (what I most heard).

    So,

            Socket sck = new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp);
    
            sck.Connect(ip, port);
            sck.Send(Encoding.UTF8.GetBytes("THE HTTP REQUEST HEADER"));
            Console.WriteLine("SENT");
            string message = null;
            byte[] bytesStored = new byte[sck.ReceiveBufferSize];
            int k1 = sck.Receive(bytesStored);
            for (int i = 0; i < k1; i++)
            {
                message = message + Convert.ToChar(bytesStored[i]).ToString();
            }
            Console.WriteLine(message); // PRINT THE RESPONSE
    

    I tested on several sites and it works perfectly. If it didn't work, then you should fix it by adding more header (most likely solution).

    0 讨论(0)
  • 2020-12-06 06:20

    I know nothing about SNP. Your code is a bit confusing on the receive part. I have used the example bellow to send and read server response for an HTTP GET request. First let's take a look at the request and then examine the response.

    HTTP GET request :

    GET / HTTP/1.1
    Host: 127.0.0.1
    Connection: keep-alive
    Accept: text/html
    User-Agent: CSharpTests
    
    string - "GET / HTTP/1.1\r\nHost: 127.0.0.1\r\nConnection: keep-alive\r\nAccept: text/html\r\nUser-Agent: CSharpTests\r\n\r\n"
    

    Server HTTP response header :

    HTTP/1.1 200 OK
    Date: Sun, 07 Jul 2013 17:13:10 GMT
    Server: Apache/2.4.4 (Win32) OpenSSL/0.9.8y PHP/5.4.16
    Last-Modified: Sat, 30 Mar 2013 11:28:59 GMT
    ETag: \"ca-4d922b19fd4c0\"
    Accept-Ranges: bytes
    Content-Length: 202
    Keep-Alive: timeout=5, max=100
    Connection: Keep-Alive
    Content-Type: text/html
    
    string - "HTTP/1.1 200 OK\r\nDate: Sun, 07 Jul 2013 17:13:10 GMT\r\nServer: Apache/2.4.4 (Win32) OpenSSL/0.9.8y PHP/5.4.16\r\nLast-Modified: Sat, 30 Mar 2013 11:28:59 GMT\r\nETag: \"ca-4d922b19fd4c0\"\r\nAccept-Ranges: bytes\r\nContent-Length: 202\r\nKeep-Alive: timeout=5, max=100\r\nConnection: Keep-Alive\r\nContent-Type: text/html\r\n\r\n"
    

    I have purposely ommited the body of the server response, because we already know it is exactly 202 bytes, as specified by Content-Length in the response header.

    A look over the HTTP specification will reveal that an HTTP header ends with an empty new line ("\r\n\r\n"). So we just need to search for it.

    Let's see some code in action. Assume a variable socket of type System.Net.Sockets.Socket.

    socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    socket.Connect("127.0.0.1", 80);
    string GETrequest = "GET / HTTP/1.1\r\nHost: 127.0.0.1\r\nConnection: keep-alive\r\nAccept: text/html\r\nUser-Agent: CSharpTests\r\n\r\n";
    socket.Send(Encoding.ASCII.GetBytes(GETrequest));
    

    We have sent the request to the server, let's receive and correctly parse the response.

    bool flag = true; // just so we know we are still reading
    string headerString = ""; // to store header information
    int contentLength = 0; // the body length
    byte[] bodyBuff = new byte[0]; // to later hold the body content
    while (flag)
    {
    // read the header byte by byte, until \r\n\r\n
    byte[] buffer = new byte[1];
    socket.Receive(buffer, 0, 1, 0);
    headerString += Encoding.ASCII.GetString(buffer);
    if (headerString.Contains("\r\n\r\n"))
    {
        // header is received, parsing content length
        // I use regular expressions, but any other method you can think of is ok
        Regex reg = new Regex("\\\r\nContent-Length: (.*?)\\\r\n");
        Match m = reg.Match(headerString);
        contentLength = int.Parse(m.Groups[1].ToString());
        flag = false;
        // read the body
        bodyBuff = new byte[contentLength];
        socket.Receive(bodyBuff, 0, contentLength, 0);
    }
    }
    Console.WriteLine("Server Response :");
    string body = Encoding.ASCII.GetString(bodyBuff);
    Console.WriteLine(body);
    socket.Close();
    

    This is probably the worst method to do this in C#, there are tons of classes to handle HTTP requests and responses in .NET, but still if you needed it, it works.

    0 讨论(0)
提交回复
热议问题