1. 程式人生 > >使用HttpListener 實現簡單的web伺服器

使用HttpListener 實現簡單的web伺服器

using System;
using System.Net;
using System.IO;
using System.Threading;
using System.Text;
using MySql.Data.MySqlClient;
using System.Collections.Generic;



public class TheServer
{

    private string result = "";
    private MySqlConnection conn;
    private HttpListener _listener;
    private Thread _threadWatchPort;
    private DataBaceTool Tool = new DataBaceTool();
    // private List<Dictionary<string, object>> Listinfo;

    static void Main(String[] args)
    {
        if (!HttpListener.IsSupported)
        {
            Console.Write("系統不支援HttpListener");
        }
        else
        {
            Console.Write("系統支援HttpListener");
        }
        TheServer Start = new TheServer();

        Start.StartListening();//開始監聽
        Start.Tool.OpenDataBace();//開啟資料庫
                             //  Start.QueryAllData("AirportManager");
    }//檢測系統支援不支援
 
    public void StartListening()
    {
        Console.Write("開始監聽" );
        _listener = new HttpListener();
        _listener.AuthenticationSchemes = AuthenticationSchemes.Anonymous;
        _listener.Prefixes.Add("http://+:8080/");
        _listener.Start(); //開始監聽埠,接收客戶端請求
        _threadWatchPort = new Thread(WatchPort);
        _threadWatchPort.Start();
        Console.Write("開啟了埠");
    }//開啟8080埠並監聽

    private void WatchPort()
    {
        while (true)
        {
            try
            {
                HttpListenerContext context = _listener.GetContext(); //等待請求連線,沒有請求則GetContext處於阻塞狀態
                context.Request.Headers.Add("Access-Control-Allow-Origin", "*");
                context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
                HttpListenerRequest request = context.Request; //客戶端傳送過來的訊息
                var reader = new StreamReader(request.InputStream);
                var msg = reader.ReadToEnd();//解析傳過來的資訊
                //http://192.168.0.1:8080/airport?query=jichang
                Tool.OpenDataBace();
                //上傳機場資訊
                string inserAirportInfoData = context.Request.QueryString[Messages.insertAirportInfo];
                if (inserAirportInfoData != null)
                {

                    inserAirportInfoData = inserAirportInfoData.Remove(inserAirportInfoData.Length - 18, 18);
                    Tool.ClearDataFromTable("AirportManager");
                    //將字串轉為 陣列字典(此處如何解析須與服務端傳過來的資料格式匹配)
                    List<Dictionary<string, object>> infoList = StringToListForDictionary(inserAirportInfoData);
                    Tool.InsertAirportData("AirportManager", infoList);
                }
                HttpListenerResponse response = context.Response;
                context.Response.StatusCode = 200;//設定返回給客服端http狀態程式碼
                string responseString = result;
                byte[] buffer = Encoding.UTF8.GetBytes(responseString);
                response.ContentLength64 = buffer.Length;
                Stream output = response.OutputStream;
                output.Write(buffer, 0, buffer.Length); //服務端傳送回訊息給客戶端
                output.Close();
            }
            catch (Exception exc)
            {
                Console.Write("--有異常-----------" + exc);
                break;
            }

            Console.Write("\n****************************訊息處理完成****************************\n");
        }
    }
}

注意此處

string inserAirportInfoData = context.Request.QueryString[Messages.insertAirportInfo];

Messages 是定義的協議類, 通過這個協議引數 來判斷 客服端傳過的時哪個訊息

using System;

public class Messages
{

    public const string insertAirportInfo = "insertAirportInfo";//上傳機場資訊
    public const string queryAllFlightInfo = "queryAllFlightInfo";//獲取航班資訊
    public const string queryPlaneInfo = "queryPlaneInfo";//獲取飛機資料
    public const string queryLandingPlaneInfo = "queryLandingPlaneInfo";//請求航線降落
    public const string updatePlaneState = "updatePlaneState";//更改飛行狀態
    public const string updatePlaneReturn = "updatePlaneReturn";//更改航班時間讓航班返航
    public const string insertFlightInfo = "insertFlightInfo";//插入航班面板資訊
    public const string queryAirportWeather = "queryAirportWeather";//獲取天氣
    public const string updateAirportWeather = "updateAirportWeather";//更新天氣
    public const string deleteAirline = "deleteAirline";//刪除航線 

    public const string queryFlightInfoFromOperation = "queryFlightInfoFromOperation";//查詢執行中航班

    /*
     * 飛機狀態 0 為起飛  1 飛行中  2 已將落
     * 飛行狀態  1 請求降落 0 正在
     * 天氣  0 正常 1風  2 雨 3 雪 4 雷電
     * */
}

服務端程式碼就這些

下面看下客戶端如何請求

Message這個協議類 客戶端也需要建立個一樣的

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


public class QueryData : MonoBehaviour
{

 //   public TextMesh text;
    List<Dictionary<string, object>> airPortinfoList;
    public delegate void ReturnData(List<Dictionary<string, object>> list);
    public ReturnData returnAllAirportInfo;
    public ReturnData returnPlaneInfo;
    public ReturnData returnLandingPlaneInfo;
    public ReturnData returnAirportWeather;
    private string resultData = "";

    private IEnumerator coroutine;

	//我這裡的key 協議欄位 value 時要傳個伺服器的值
    public IEnumerator RequestServer( string value,string key)
    {
        string url = "http://192.168.0.1:8080/airport?" + key + "=" + value;
        url.Replace(" ", "");//字串需要過濾掉
        WWW www = new WWW(url);
        yield return www;
        if (string.IsNullOrEmpty(www.error))
        {
            resultData = www.text;
           www.Dispose();
            GetData(key);
        }
    }



    private void GetData(string key)
    {
      //  Debug.Log(key + "============");
        if (resultData.Equals("true"))
        {
            return;
        }
        if(key == Messages.queryAirportWeather)
        {
            if(returnAirportWeather != null)
            {
				//如果有返回值 返回值將在resultData裡
                List<Dictionary<string, object>> list = StringToListForDictionary(resultData);
                returnAirportWeather(list);
            }
        }
       
        return;
    }