zoukankan      html  css  js  c++  java
  • 基于windows服务的本地监听程序 实现服务提供

      业务功能背景描述 ,需要通过web页面访问本地服务程序实现启动第三方程序。

    具体实现方式在本地实现固定端口的监听,实现接受第三方程序发出的指令及参数,完成逻辑判断,返回信息。

    1.监听抽象类:
    public abstract class HttpServer
    {

    protected int port;
    protected string ip;
    TcpListener listener;
    bool is_active = true;

    public HttpServer(int port, string ip)
    {
    if (string.IsNullOrEmpty(ip))
    {
    this.port = 2341;
    this.ip = "127.0.0.1";
    }
    else
    {
    this.port = port;
    this.ip = ip;
    }
    }

    public void listen()
    {
    listener = new TcpListener(IPAddress.Parse(ip), port);
    listener.Start();
    while (is_active)
    {
    TcpClient s = listener.AcceptTcpClient();
    HttpProcessor processor = new HttpProcessor(s, this);
    Thread thread = new Thread(new ThreadStart(processor.process));
    thread.Start();
    Thread.Sleep(1);
    }
    }

    public abstract void handleGETRequest(HttpProcessor p);
    public abstract void handlePOSTRequest(HttpProcessor p, StreamReader inputData);
    }

    2.监听实现类


    public class MyHttpServer : HttpServer
    {

    public MyHttpServer(int port, string ip)
    : base(port, ip)
    {
    }

    public override void handleGETRequest(HttpProcessor p)
    {

    if (p.httpHeaders.ContainsKey("URL"))
    {
    string url = p.httpHeaders["URL"].ToString();
    url = HttpUtility.UrlDecode(url);
    if (string.IsNullOrEmpty(p.path))
    {
    System.Diagnostics.Process.Start(url);
    }
    else
    {
    try
    {
    System.Diagnostics.Process.Start(p.path, url);
    }
    catch (Exception)
    {

    System.Diagnostics.Process.Start(url);
    }
    }

    }
    Console.WriteLine("request: {0}", p.http_url);
    p.writeSuccess();
    p.outputStream.WriteLine("<html><body><h1>test server</h1>");
    p.outputStream.WriteLine("Current Time: " + DateTime.Now.ToString());
    p.outputStream.WriteLine("url : {0}", p.http_url);

    p.outputStream.WriteLine("<form method=post action=/form>");
    p.outputStream.WriteLine("<input type=text name=foo value=foovalue>");
    p.outputStream.WriteLine("<input type=submit name=bar value=barvalue>");
    p.outputStream.WriteLine("</form>");
    }

    public override void handlePOSTRequest(HttpProcessor p, StreamReader inputData)
    {
    Console.WriteLine("POST request: {0}", p.http_url);
    string data = inputData.ReadToEnd();
    p.writeSuccess();
    p.outputStream.WriteLine("<html><body><h1>test server</h1>");
    p.outputStream.WriteLine("<a href=/test>return</a><p>");
    p.outputStream.WriteLine("postbody: <pre>{0}</pre>", data);
    }


    }

    3.处理解析类

    public class HttpProcessor
    {
    public TcpClient socket;
    public HttpServer srv;
    // public string callurl = System.Configuration.ConfigurationManager.AppSettings["callurl"];
    public string path = "";// System.Configuration.ConfigurationManager.AppSettings["path"];
    public string defualturl ="http://www.baidu.com";// System.Configuration.ConfigurationManager.AppSettings["defualt"];
    private StreamReader inputStream;
    public StreamWriter outputStream;

    public String http_method;
    public String http_url;
    public String http_protocol_versionstring;
    public Hashtable httpHeaders = new Hashtable();


    private static int MAX_POST_SIZE = 10 * 1024 * 1024; // 10MB

    public HttpProcessor(TcpClient s, HttpServer srv)
    {
    this.socket = s;
    this.srv = srv;
    this.path = BrowsersData();
    }

    public string BrowsersData()
    {
    string path = "";
    RegistryKey browsersKey;
    browsersKey = Registry.LocalMachine.OpenSubKey(@"SOFTWAREWOW6432NodeClientsStartMenuInternet");
    if (browsersKey == null)
    browsersKey = Registry.LocalMachine.OpenSubKey(@"SOFTWAREClientsStartMenuInternet");
    using (browsersKey)
    {
    string[] subKeys = browsersKey.GetSubKeyNames();
    string locationPath = @"DefaultIcon";
    Hashtable ht = new Hashtable();
    foreach (string key in subKeys)
    {

    RegistryKey appLocationKey = browsersKey.OpenSubKey(key + locationPath);
    // Console.WriteLine("{0}:{1}", key, (string)appLocationKey.GetValue(null));
    string key1 = key.ToUpper();
    string pathtemp =((string)appLocationKey.GetValue(null)).Split(',')[0];
    if (key1.Contains("360"))
    {
    ht.Add("360", pathtemp);
    }
    else if (key1.Contains("IE"))
    {
    ht.Add("IE", pathtemp);
    }
    else if (key1.Contains("TSB"))
    {
    ht.Add("TSB", pathtemp);
    }
    else if (key1.Contains("CHROME"))
    {
    ht.Add("CHROME", pathtemp);

    }
    else
    {
    ht.Add(key, pathtemp);
    }
    appLocationKey.Close();
    }
    if (ht.Contains("CHROME"))
    {
    path = ht["CHROME"].ToString();
    return path;
    }
    if ((ht.Contains("TSB")))
    {
    path = ht["TSB"].ToString();
    return path;
    }
    if ((ht.Contains("360")))
    {
    path = ht["360"].ToString();
    return path;
    }
    if ((ht.Contains("IE")))
    {
    path = ht["IE"].ToString();
    return path;
    }
    return path;
    }
    }


    public void process()
    {
    // bs = new BufferedStream(s.GetStream());
    inputStream = new StreamReader(socket.GetStream());
    outputStream = new StreamWriter(new BufferedStream(socket.GetStream()));
    try
    {
    parseRequest();
    readHeaders();
    if (http_method != null)
    {
    if (http_method.Equals("GET"))
    {
    handleGETRequest();
    }
    else if (http_method.Equals("POST"))
    {
    handlePOSTRequest();
    }
    }
    }
    catch (Exception e)
    {
    Console.WriteLine("异常消息: " + e.ToString());
    writeFailure();
    }
    outputStream.Flush();
    // bs.Flush(); // flush any remaining output
    inputStream = null; outputStream = null; // bs = null;
    socket.Close();
    }

    public void parseRequest()
    {
    String request = inputStream.ReadLine();
    if (request == null)
    {
    request = "";
    }
    string[] tokens = request.Split(' ');
    if (tokens.Length != 3)
    {
    Console.WriteLine("starting no invalid http request line");

    }
    else
    {
    http_method = tokens[0].ToUpper();
    http_url = tokens[1];
    http_protocol_versionstring = tokens[2];

    Console.WriteLine("starting: " + request);
    }
    }

    /// <summary>
    /// 获取请求头部信息
    /// </summary>
    public void readHeaders()
    {
    Console.WriteLine("readHeaders()");
    String line;

    while ((line = inputStream.ReadLine()) != null)
    {
    if (line.Equals(""))
    {
    Console.WriteLine("got headers");
    return;
    }

    int separator = line.IndexOf(':');
    if (separator == -1)
    {
    throw new Exception("invalid http header line: " + line);
    }
    String name = line.Substring(0, separator);
    int pos = separator + 1;
    while ((pos < line.Length) && (line[pos] == ' '))
    {
    pos++; // strip any spaces
    }

    string value = line.Substring(pos, line.Length - pos);
    name = name.ToUpper();
    Console.WriteLine("header: {0}:{1}", name, value);
    httpHeaders[name] = value;
    }
    }

    public void handleGETRequest()
    {
    srv.handleGETRequest(this);
    }

    public void handlePOSTRequest()
    {
    try
    {
    Console.WriteLine("get post data start");
    int content_len = 0;
    MemoryStream ms = new MemoryStream();
    string url = defualturl;
    if (this.httpHeaders.ContainsKey("CONTENT-LENGTH") || this.httpHeaders.ContainsKey("content-length"))
    {
    content_len = Convert.ToInt32(this.httpHeaders["CONTENT-LENGTH"]);
    Console.WriteLine("Content-Length=" + content_len);
    if (content_len > MAX_POST_SIZE)
    {
    throw new Exception(
    String.Format("POST Content-Length({0}) too big for this simple server",
    content_len));
    }
    byte[] buf = new byte[4096];
    char[] chaf = new char[1000];
    int to_read = content_len;
    int numread = this.inputStream.Read(chaf, 0, content_len);

    string value = new string(chaf).Trim();
    if (value.Split('&').Length>1)
    url = value.Split('&')[0].Split('=')[1];
    Console.WriteLine("url" + url);
    buf = Encoding.UTF8.GetBytes(value);
    ms.Write(buf, 0, buf.Length);
    ms.Seek(0, SeekOrigin.Begin);
    }
    url = HttpUtility.UrlDecode(url);
    Console.WriteLine( "url:" + url);
    if ( string.IsNullOrEmpty(url))
    {
    url = defualturl;
    }
    if (string.IsNullOrEmpty(path))
    {
    System.Diagnostics.Process.Start( url);
    }
    else
    {
    try
    {
    System.Diagnostics.Process.Start(path, url);
    }
    catch (Exception )
    {

    System.Diagnostics.Process.Start( url);
    }
    }
    //PostHttp(callurl,"","application/x-www-form-urlencoded");
    Console.WriteLine("get post data end");
    srv.handlePOSTRequest(this, new StreamReader(ms));
    }
    catch (Exception ex)
    {

    Console.WriteLine("错误信息" + ex.Message);
    }

    }

    public void writeSuccess()
    {
    outputStream.Write("HTTP/1.0 200 OK ");
    outputStream.Write("Content-Type: text/html ");
    outputStream.Write("Access-Control-Allow-Origin: *");
    outputStream.Write("Connection: close ");
    outputStream.Write(" ");
    }

    public void writeFailure()
    {
    outputStream.Write("HTTP/1.0 404 File not found ");
    outputStream.Write("Connection: close ");
    outputStream.Write(" ");
    }

    public string PostHttp(string url, string body, string contentType)
    {
    HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
    //application/x-www-form-urlencoded
    httpWebRequest.ContentType = contentType;
    httpWebRequest.Method = "POST";
    httpWebRequest.Timeout = 20000;

    byte[] btBodys = Encoding.UTF8.GetBytes(body);
    httpWebRequest.ContentLength = btBodys.Length;
    httpWebRequest.GetRequestStream().Write(btBodys, 0, btBodys.Length);

    HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
    StreamReader streamReader = new StreamReader(httpWebResponse.GetResponseStream());
    string responseContent = streamReader.ReadToEnd();

    httpWebResponse.Close();
    streamReader.Close();
    httpWebRequest.Abort();
    httpWebResponse.Close();

    return responseContent;
    }

    public string CreateHttpRequest(string post)
    {
    StringBuilder sb = new StringBuilder();
    sb.Append(@"<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' xmlns:exc=访问地址'>");
    sb.Append("<soapenv:Header/>");
    sb.Append("<soapenv:Body>");
    sb.Append("<exc:HisWxEccute>");
    sb.Append("<exc:xmlString>");
    sb.Append(post);
    sb.Append("</exc:xmlString>");
    sb.Append("</exc:HisWxEccute>");
    sb.Append("</soapenv:Body>");
    sb.Append("</soapenv:Envelope>");
    return sb.ToString();
    }

    public void callservice(string req,string Url)
    {
    string input = CreateHttpRequest(req);
    // string result = WebRequestHelper.Current.HttpPost(Url, input, Encoding.UTF8, Encoding.UTF8);
    }


    }

    5.调用实现方法 新建一个windows服务程序 ,并把它做成windows安装程序


    public partial class Service1 : ServiceBase
    {
    public Service1()
    {
    InitializeComponent();
    }

    protected override void OnStart(string[] args)
    {

    // string input =System.Configuration.ConfigurationManager.AppSettings["port"];

    int port = 2000;// Regex.IsMatch(input, @"^[+-]?d*[.]?d*$") ? Convert.ToInt32(input) : 2000;
    string ip = "127.0.0.1";//System.Configuration.ConfigurationManager.AppSettings["ip"];
    HttpServer httpServer;
    httpServer = new MyHttpServer(port,ip);
    Thread thread = new Thread(new ThreadStart(httpServer.listen));
    thread.Start();
    Console.WriteLine("服务已启动!");
    }

    protected override void OnStop()
    {
    Console.WriteLine("服务已关闭!");
    }
    }

    1.实现效果如下: 启动本地服务  ,并在浏览器服务2000端口 就会启动相关的程序。

  • 相关阅读:
    阻止元素默认行为
    微信小程序--页面的生命周期和参数传递
    微信小程序-查询快递
    小程序-冒泡事件
    SpringMVC-使用、运行流程、配置文件寻找
    OpenCV-安装使用、图像处理
    Spring-AOP:JoinPoint、各种通知、基于XML和注解的AOP、声明式事务
    Spring-AOP:开发准备、初识动态代理、使用步骤、
    Spring-IOC:Bean的作用域、生命周期、XML的装配、注解注入、@Autowired
    Spring-IOC:复杂值注入、各种类型赋值、bean的复用
  • 原文地址:https://www.cnblogs.com/xplangren/p/10737538.html
Copyright © 2011-2022 走看看