tags:

views:

56

answers:

2

Hello everybody.

I would like to know how to download and save a file to my hard drive, specifically a zip file from a HTTP server using the System.Net.Socket.Sockets class.

I know there are allot easier ways to download a file with .Net, but i would like to know how to do it with Sockets, if possible of course although I'm pretty sure it is.

I've tried a few things, nothing worked once i don't have any background experience with sockets.

Your help satisfying my curiosity is appreciated. Any question just ask. Thank you.

Note:

  • The file is a standard zip file, however i would like a way that would work with any file type.
  • The file size is different every day.
  • The file is downloaded every minute, caching of such file must be disabled to get a accurate and update file version from the server.
  • File url sample: www.somewhere.com/files/feed/list.zip
+2  A: 

You could do this directly with a .NET socket, but it would require parsing and understanding the HTTP request.

The standard way to do this would just be to use the higher level System.Net classes. For example, this can be done in two lines of code via WebClient.DownloadFile - why make life more difficult for yourself?


If you really must do this from raw sockets, it will just take a lot of work. At it's core, you can connect to port 80 (assuming http) via a TCP connection, write the correct strings to the socket, and start receiving data.

That being said, getting everything correct, and handling all of the issues required is far beyond a standard StackOverflow answer's scope. If you want to go down this road, take a look at the HTTP Protocol specifications - you'll need to implement the proper aspects of this specification.

Reed Copsey
@Reed: I already use the easy ways, i would like to know and understand the hard way. Which basically is the backbone for the easy way, correct me if I'm wrong.
Fábio Antunes
@Fábio Antunes: I edited my answer to give you the guidance you'd need for this, if you want to go "beyond the simple ways".
Reed Copsey
@Reed: Any suggestion, tips, dos and don't dos, and a special tool to monitor traffic is appreciated?
Fábio Antunes
@Fabio you can use wireshark to sniff traffic and understand which part is the header and which is the payload
@Reed: The HTTP Protocol specs url you posted on your answer most of the links there end up in dead ends, 404 not found. Could you have a look at it? And find where they went?
Fábio Antunes
@Fábio Antunes: You can get the entire spec here - http://www.w3.org/Protocols/HTTP/1.1/rfc2616.pdf
Reed Copsey
@Reed: Thanks reed. I also got some results, i got the content of the file, i can print it to the console, like it was opened in notepad. Funny thing the console keeps beeping after the download and printing it, for some reason i don't know. Thanks Reed.
Fábio Antunes
A: 

Hi,

For this you can simply use the "HttpWebRequest" and "HttpWebResponse" classes in .net.

Below is a sample console app I wrote to demonstrate how easy this is.

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            string url = "www.somewhere.com/files/feed/list.zip";       
            string fileName = @"C:\list.zip";

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Timeout = 5000;

            try
            {
                using (WebResponse response = (HttpWebResponse)request.GetResponse())
                {
                    using (FileStream stream = new FileStream(fileName, FileMode.Create, FileAccess.Write))
                    {
                        byte[] bytes = ReadFully(response.GetResponseStream());

                        stream.Write(bytes, 0, bytes.Length);
                    }
                }
            }
            catch (WebException)
            {
                Console.WriteLine("Error Occured");
            }
        }

        public static byte[] ReadFully(Stream input)
        {
            byte[] buffer = new byte[16 * 1024];
            using (MemoryStream ms = new MemoryStream())
            {
                int read;
                while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
                {
                    ms.Write(buffer, 0, read);
                }
                return ms.ToArray();
            }
        }
    }
}

Enjoy!

Doug
@Doug: I appreciate. But i want to use Sockets, which i suppose is the backbone for all others, including `HttpWebRequest`, `WebClient`, ... Thanks for the code any way.
Fábio Antunes
@Fábio Antunes You can use the Redgate reflector to look at the underlying source code of the HttpWebRequest and HttpWebResponse if you really want to see how it is done at the socket level.. http://www.red-gate.com/products/reflector/
Doug
@Doug: +1. Useful tool indeed, thanks.
Fábio Antunes