Http on C#

Http通信をするプログラムを書いてみた。.netのライブラリにもとからあるのだが、なんか遅いと感じるのと、ファイルの存在の調べ方がいまいちよく分からなかったのでHEADコマンドによってファイルの存在を調べるプログラムを書いた。

public static int Head(string Host, string Path)
{
    const string Command = "HEAD";
    var tcpClient = new TcpClient();

    tcpClient.Connect(Host, 80);
    var netStream = tcpClient.GetStream();

    byte[] buf;
    buf = Encoding.ASCII.GetBytes(Command + ' ' + Path + " HTTP/1.0\r\n");
    netStream.Write(buf, 0, buf.Length);
    buf = Encoding.ASCII.GetBytes("Host: " + Host + "\r\n\r\n");
    netStream.Write(buf, 0, buf.Length);
    buf = null;
    netStream.Flush();


    var res = ReadLine(netStream);
    netStream.Dispose();
    tcpClient.Close();

    return int.Parse(res.Split(' ')[1]);

    // 以下、到達できないコード

    // Header
    while (true)
    {
        var read = ReadLine(netStream);
        if (read == "")
            break;

        var readsplit = read.Split(':');
        readsplit[1] = readsplit[1].TrimStart(' ');
        Console.WriteLine("{0}\t{1}", readsplit[0], readsplit[1]);
    }

    // Message Body
    // ただし、CommandがGETでないとデータは来ない
    string SavePath = null;
    const int BufferSize = 1024;
    using (FileStream fs = new FileStream(SavePath, FileMode.CreateNew))
    {
        byte[] BufferData = new byte[BufferSize];
        while (true)
        {
            var ReceivedSize = netStream.Read(BufferData, 0, BufferSize);
            fs.Write(BufferData, 0, ReceivedSize);

            if (ReceivedSize == 0)
                break;
        }
    }
}
static string ReadLine(Stream stream)
{
    StringBuilder sb = new StringBuilder();
    while (true)
    {
        int read = stream.ReadByte();
        switch (read)
        {
            case '\r':
                read = stream.ReadByte();
                if (read == '\n')
                    return sb.ToString();
                else
                {
                    sb.Append('\r');
                    sb.Append((char)read);
                    break;
                }
            case '\n':
                read = stream.ReadByte();
                if (read == '\r')
                    return sb.ToString();
                else
                {
                    sb.Append('\n');
                    sb.Append((char)read);
                    break;
                }
            default:
                sb.Append((char)read);
                break;
        }
    }
}

ちなみにreturn以下のコードには到達できないが、Command="GET";にしてあとは適当に書き換えてあげれば、ヘッダ情報やデータ内容をダウンロードすることができる。



次の目標はMMS/RTSPかな(笑)
日本語のドキュメントがあればいいんだけれど…



SMTPがやりたいって人はこのエントリのあたりを参照してみてください