[UWP] Windows 10 IoT 製作一個小小的Server.

2015-09-07


目前10240 版本中,還沒有IIS ,本來想說可以寫一些網頁來控制的,不過目前網路上看官方的一些範例,是可以透過自己實作一個httpD ,所以我也動手實作看看,當然我改寫了一部分,我直接讓他可以讀取專案下面 Assets\html\ 的所有檔案

1
. 一開始實作一個 TinyHttpdServer  繼承 IDisposable


public sealed class TinyHttpdServer : IDisposable
{
   //..

2.之後宣告一個  StreamSocketListener ,其實重點都在實作他


private readonly StreamSocketListener listener;

3. 其中讓他的 ConnectionReceived  必須要實作


listener.ConnectionReceived += (s, e) =>
                           ProcessRequestAsync(e.Socket);
 
/// <summary>
/// 處理當ConnectionReceived 的時候
/// </summary>
/// <param name="socket"></param>
private async void ProcessRequestAsync(StreamSocket socket)
{
    // this works for text only
    StringBuilder request = new StringBuilder();
    using (IInputStream input = socket.InputStream)
    {
        byte[] data = new byte[BufferSize];
        IBuffer buffer = data.AsBuffer();
        uint dataRead = BufferSize;
        while (dataRead == BufferSize)
        {
            await input.ReadAsync(buffer, BufferSize, InputStreamOptions.Partial);
            request.Append(Encoding.UTF8.GetString(data, 0, data.Length));
            dataRead = buffer.Length;
        }
    }
 
    using (IOutputStream output = socket.OutputStream)
    {
        string requestMethod = request.ToString().Split('\n')[0];
        string[] requestParts = requestMethod.Split(' ');
 
        if (requestParts[0] == "GET")
            await WriteResponseAsync(requestParts[1], output);
        else
            throw new InvalidDataException("HTTP method not supported: "
                                           + requestParts[0]);
    }
}

4.輸出的資料,我將資料直接對應至Assets/html/ ,我有簡單的處理MIME


/// <summary>
/// 輸出的資料
/// </summary>
/// <param name="request">http://網址  以後的東西 
/// ex. http://1xx.xx.xx.xx/sample.html 則此參數呈現  /sample.html</param>
/// <param name="os"></param>
/// <returns></returns>
private async Task WriteResponseAsync(string request, IOutputStream os)
{
    string file = @"Assets\html" + request.Replace("\\", "/");
 
 
    if (request == "/")
    {
        file = @"Assets\html\index.html";
    }
    else if (!System.IO.File.Exists(file))
    {
        file = @"Assets\html\404.html";
    }
    using (Stream resp = os.AsStreamForWrite())
    {
        var contentType = "text/html";
        if (System.IO.Path.GetExtension(file).ToLower() == ".jpg" ||
            System.IO.Path.GetExtension(file).ToLower() == ".png" ||
            System.IO.Path.GetExtension(file).ToLower() == ".jpeg")
        {
            contentType = "image/jpeg";
        }
 
        //很簡單的處理jpg and html 只是測試,別太講究
        //Handling MIME and Head roughly.
        byte[] bodyArray = File.ReadAllBytes(file);
        MemoryStream stream = new MemoryStream(bodyArray);
        string header = String.Format("HTTP/1.1 200 OK\r\n" +
                                      "Content-Length: {0}\r\n" +
                                       "content-type: {1}\r\n" +
                                      "Connection: close\r\n\r\n",
            stream.Length, contentType);
        byte[] headerArray = Encoding.UTF8.GetBytes(header);
        await resp.WriteAsync(headerArray, 0, headerArray.Length);
        await stream.CopyToAsync(resp);
        await resp.FlushAsync();
    }
    
}

5.呼叫,我開啟的5978的port

TinyHttpdServer ths=new TinyHttpdServer(5978);
ths.Start();

6.打開權限,Internet(Client) 、 Internet(Client & Server )
image

7
. 很重要所以我要說三次
不要用本機電腦開瀏覽器測試,換一台同網域的其他電腦
不要用本機電腦開瀏覽器測試,換一台同網域的其他電腦
不要用本機電腦開瀏覽器測試,換一台同網域的其他電腦

  結果:
image
圖片測試
unnamed

Reference:
https://dev.windows.com/en-us/samples
https://www.hackster.io/windowsiot/blinky-webserver-sample


source code:
https://github.com/donma/Windows10IoT-TinyHttpServer


當麻許的超技八 2014 | Donma Hsu Design.