HttpListener 实现web服务端

1.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
using System.IO;

namespace HttpListen
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] arr = { "http://localhost:37090/", "http://zhihu.org.cn/a/" };
          //  SimpleListenerExample(arr);
           // test1(arr[1]);
            HttpServer httpServer;
            //if (args.GetLength(0) > 0)
            //{
            //httpServer = new MyHttpServer(Convert.ToInt16(args[0]));
            httpServer = new MyHttpServer(2345);
            //} else {
            //    httpServer = new MyHttpServer(8080);
            //}
            Thread thread = new Thread(new ThreadStart(httpServer.listen));
            thread.Start();

        }

        //方法1
        // This example requires the System and System.Net namespaces.
        public static void SimpleListenerExample(string[] prefixes)
        {
            if (!HttpListener.IsSupported)
            {
                Console.WriteLine("Windows XP SP2 or Server 2003 is required to use the HttpListener class.");
                return;
            }
            // URI prefixes are required,
            // for example "http://contoso.com:8080/index/".
            if (prefixes == null || prefixes.Length == 0)
                throw new ArgumentException("prefixes");

            // Create a listener.
            HttpListener listener = new HttpListener();
            // Add the prefixes.
            foreach (string s in prefixes)
            {
                listener.Prefixes.Add(s);
            }
            listener.Start();
            Console.WriteLine("Listening...");

            Task.Factory.StartNew(() =>
            {

                // Note: The GetContext method blocks while waiting for a request.
                HttpListenerContext context = listener.GetContext();
                HttpListenerRequest request = context.Request;
                // Obtain a response object.
                HttpListenerResponse response = context.Response;
                // Construct a response.
                string responseString = "<HTML><BODY> Hello world!</BODY></HTML>";
                byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
                // Get a response stream and write the response to it.
                response.ContentLength64 = buffer.Length;
                System.IO.Stream output = response.OutputStream;
                output.Write(buffer, 0, buffer.Length);
                // You must close the output stream.
                output.Close();
                //  listener.Stop();

            });

            Console.WriteLine("ok");
            Console.ReadLine();
        }

        //方法2
        public static void test1(string url)
        {
            HttpListener httpListener = new HttpListener();

            httpListener.AuthenticationSchemes = AuthenticationSchemes.Anonymous;
            httpListener.Prefixes.Add(url);
            Console.WriteLine("开始监听··········");
            httpListener.Start();
            new Thread(new ThreadStart(delegate
            {
                while (true)
                {

                    HttpListenerContext httpListenerContext = httpListener.GetContext();
                    httpListenerContext.Response.StatusCode = 200;
                    using (StreamWriter writer = new StreamWriter(httpListenerContext.Response.OutputStream))
                    {
                        writer.WriteLine("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/><title>测试服务器</title></head><body>");
                        writer.WriteLine("<div style=\"height:20px;color:blue;text-align:center;\"><p> hello</p></div>");
                        writer.WriteLine("<ul>");
                        writer.WriteLine("</ul>");
                        writer.WriteLine("</body></html>");

                    }

                }
            })).Start();

        }

    }

}

方法3类文件:

using System;
using System.Collections;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;

// offered to the public domain for any use with no restriction
// and also with no warranty of any kind, please enjoy. - David Jeske. 

// simple HTTP explanation
// http://www.jmarshall.com/easy/http/

namespace HttpListen
{

    public class HttpProcessor
    {
        public TcpClient socket;
        public HttpServer srv;

        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;
        }

        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.Equals("GET"))
                {
                    handleGETRequest();
                }
                else if (http_method.Equals("POST"))
                {
                    handlePOSTRequest();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception: " + 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();
            string[] tokens = request.Split(‘ ‘);
            if (tokens.Length != 3)
            {
                throw new Exception("invalid http request line");
            }
            http_method = tokens[0].ToUpper();
            http_url = tokens[1];
            http_protocol_versionstring = tokens[2];

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

        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);
                Console.WriteLine("header: {0}:{1}", name, value);
                httpHeaders[name] = value;
            }
        }

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

        public void handlePOSTRequest()
        {
            // this post data processing just reads everything into a memory stream.
            // this is fine for smallish things, but for large stuff we should really
            // hand an input stream to the request processor. However, the input stream
            // we hand him needs to let him see the "end of the stream" at this content
            // length, because otherwise he won‘t know when he‘s seen it all! 

            Console.WriteLine("get post data start");
            int content_len = 0;
            MemoryStream ms = new MemoryStream();
            if (this.httpHeaders.ContainsKey("Content-Length"))
            {
                content_len = Convert.ToInt32(this.httpHeaders["Content-Length"]);
                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];
                int to_read = content_len;
                while (to_read > 0)
                {
                    int numread = this.inputStream.BaseStream.Read(buf, 0, Math.Min(4096, to_read));
                    to_read -= numread;
                    ms.Write(buf, 0, numread);
                }
                ms.Seek(0, SeekOrigin.Begin);
            }
            Console.WriteLine("get post data end");
            srv.handlePOSTRequest(this, new StreamReader(ms));

        }

        public void writeSuccess()
        {
            outputStream.Write("HTTP/1.0 200 OK\n");
            outputStream.Write("Content-Type: text/html\n");
            outputStream.Write("Connection: close\n");
            outputStream.Write("\n");
        }

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

    public abstract class HttpServer
    {

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

        public HttpServer(int port)
        {
            this.port = port;
        }

        public void listen()
        {
            listener = new TcpListener(IPAddress.Parse("127.0.0.1"), 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);
    }

    public class MyHttpServer : HttpServer
    {
        public MyHttpServer(int port)
            : base(port)
        {
        }
        public override void handleGETRequest(HttpProcessor p)
        {
            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.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);
        }
    }

}
时间: 2024-08-24 11:47:50

HttpListener 实现web服务端的相关文章

如何提高Web服务端并发效率的异步编程技术

作为一名web工程师都希望自己做的web应用能被越来越多的人使用,如果我们所做的web应用随着用户的增多而宕机了,那么越来越多的人就会变得越来越少了,为了让我们的web应用能有更多人使用,我们就得提升web应用服务端的并发能力.那么我们如何做到这点了,根据现有的并发技术我们会有如下选择: 第一个做法:为每个客户端发送给服务端的请求都开启一个线程,等请求处理完毕后该线程就被销毁掉,这种做法很直观,但是在现代的web服务器里这种做法已经很少使用了,原因是新建一个线程,销毁一个线程的开销(开销是指占用

搭建一个java web服务端

最近也是做了一个简单的java web 项目,由于以前也是没接触过,在这里记录下搭建一个web服务端的过程. 一般我们做一个服务端要么在本地自己的电脑上先安装环境,一般是windows系统,主要安装jdk + tomcat + mysql,这些安装教程网上都有,也很简单,我这里就不多说了,我要讲的是在一个远程linux服务器上搭建web服务端环境. 对于一个liunx服务器,我们可以使用xshell等终端工具登录来操作远程服务器,使用xshell的好处是,我们可以使用rz ,sz命令上传上载文件

winform客户端利用webClient实现与Web服务端的数据传输

由于项目需要,最近研究了下WebClient的数据传输.关于WebClient介绍网上有很多详细介绍,大概就是利用WebClient可以实现对Internet资源的访问.无外乎客户端发送请求,服务端处理请求.回应请求.所以,我下面就简单描述下学习过程中遇到的一些问题: 1.关于Winform客户端请求 WebClient wc = new WebClient();//初始化webclient string path = "http://192.168.1.115:8089/Handler1.as

Android服务端开发1-使用Eclipse搭建Java Web服务端

本篇博客介绍如何使用Eclipse来创建一个Java Web程序,为后面讲通过Android客户端跟服务端进行交互打下基础,关于服务端可以选用的程序很多,主流的搭配是Android客户端+PHP服务端,我们也可以使用Android客户端+Java EE服务端这样的搭配,就看公司是以哪种方式提供了. 创建一个Java Web程序,没有特别复杂的流程,我们先准备一下原材料: 1. Eclipse(注:这个不是ADT Bundle,最好到官网下载针对开发Java EE的IDE,如果可以的话,选中MyE

Web服务端开发需要考虑的问题

API设计 是否Restful. 首先需要清楚,Restful是一种风格而不是规范,不存在必须遵守的问题. Restful本质上是对HTTP API进行有效的分类. 分类是应该的,可以让API组织变得有序.层次清晰 一定要以Restful的风格分类吗? Restful风格的特点 url表示的只是资源,没有动作,所以只会出现名词,不会出现动词 这样的url不对 /accounts/1/transfer/499 应该是这样 /accounts/1/transactions/499 想想传统的logi

iredmail邮件服务器之修改默认的web服务端口号

安装iredmail之后,由于需要在路由器上做端口映射以便在外网访问webmail,因此端口不能和WEB服务的端口好冲突,所以需要修改邮件服务器的httpd服务的端口. 一.apache/httpd的http服务和https服务端口号都要修改. 基本服务端口好办,iredmail默认安装下,修改/etc/httpd/conf/httpd.conf中的Listen一行即可,这里我改为8090 #Listen 80 Listen 8090 可是,roundcube的webmail服务都是使用的htt

WEB服务端安全---注入攻击

注入攻击是web领域最为常见的攻击方式,其本质是把用户输入的数据当做代码执行,主要原因是违背了数据与代码分离原则,其发生的两个条件:用户可以控制数据输入:代码拼接了用户输入的数据,把数据当做代码执行了. 下面是几种常见注入攻击及其防御方法: SQL注入及常见攻击技巧 经典注入  如: $username = $_POST['username']; $sql = "select * from usertable where username="."'".$userna

web服务端安全---文件上传漏洞

1.简述 文件上传漏洞是指用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务端命令的能力.这种攻击方式是最直接和有效的,而且互联网中我们经常会用到文件上传功能,它本身是没有问题的,正常的业务需求,可是文件上传后服务器如果不能安全有效的处理或解释文件,往往会造成严重的后果. 常见的安全问题: 上传文件是web脚本语言,服务器的web容器解释并执行了用户上传的脚本,导致代码执行: 上传文件是flash的策略文件crossdomain.xml,黑客用以控制flash在该领域下的行为: 上传

HTTP协议(2)配置Web服务端LAMP

在之前的课程中,我们都是通过Appserv或PHPStudy来搭建Web服务环境,在这里介绍如何通过CentOS7.5来搭建一个真实的LAMP(Linux+Apache+ MySQL +PHP)环境.在部署LAMP时,软件安装的一般顺序是Linux→Apache→PHP→MySQL.Apache的软件名和所对应的服务名都是httpd,在CentOS7中默认没有安装Apache.因而首先需要安装启动httpd服务,并将其设为开机自动运行. [[email protected] ~]# yum in