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

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.


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

Tags:

C#

Sockets