软件架构师何志丹

本程序仅仅是入门级程序。所以不考虑

1。多线程。

2,安全性。

3,不考虑端点下载文件。

4,Keep-Alive。

5,不考虑head。

6,为了简洁,删掉了catch的内容。



exe的祖父目录必须有wwwroot目录,且目录有index.htm,内容不限。 

开发环境: WinXP+VS2010C#



一。新建一个项目TestWeb。项目类型:Windows窗体应用程序。

二。新建类RequestProcessor。

 using System;

using System.IO;

using System.Net;

using System.Net.Sockets;

using System.Text;

using System.Threading;

using System.Diagnostics;



namespace TestWeb

{

    class RequestProcessor

    {

        public bool ParseRequestAndProcess(string[] RequestLines)//解析内容

        {

            for (int i = 0; i < RequestLines.Length; i++)

                System.Diagnostics.Trace.Write(RequestLines[i]);



            char[] sp = new Char[1] { ' ' };

            string[] strs = RequestLines[0].Split(sp);

            if (strs[0] == "GET")

            {

                Send(strs[1], 0, 0);

            }



            return false;

        }



        void Send(string filename, long start, long length)//发送文件(文件头和文件)

        {

            string strFileName = GetPathFileName(filename);

            FileStream fs = null;

            try

            {

                fs = new FileStream(strFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);



            }

            catch (IOException)// FileNotFoundException)

            {//不能将 e.Message,发给浏览器,否则会有安全隐患的

                SendHeadrAndStr("打开文件" + filename + "失败。

");

                return;

            }



            if (length == 0)

                length = fs.Length - start;



            SendHeader("text/html", (fs.Length == length), start, length);

            sendContent(fs, start, length);

        }



        public void SendHeadrAndStr(String str)//直接将str的内容发给html

        {

            byte[] sendchars = Encoding.Default.GetBytes((str).ToCharArray());

            SendHeader("text/html", true, 0, sendchars.Length);

            SendStr(Encoding.Default, str);

        }



        private void SendHeader(string fileType, bool bAll, long start, long length)//发送文件头

        {

            try

            {

                Encoding coding = Encoding.Default;

                string strSend;

                string strState = (bAll) ?

"HTTP/1.1 200 OK" : "HTTP/1.1 206 Partial Content";

                SendStr(coding, strState + "\r\n");

                SendStr(coding, "Date: \r\n");

                SendStr(coding, "Server: httpsrv/1.0\r\n");

                SendStr(coding, "MIME-Version: 1.0\r\n");

                SendStr(coding, "Content-Type: " + fileType + "\r\n");





                strSend = "Content-Length: " + length.ToString();

                SendStr(coding, strSend + "\r\n");



                //发送一个空行

                SendStr(coding, "\r\n");

            }

            catch (ArgumentException)//the request is WRONG

            {





            }



        }



        private void sendContent(FileStream fs, long start, long length)//发生文件内容

        {

            try

            {



                //报文头发送完成,開始发送正文

                const int SOCKETWINDOWSIZE = 8192;

                long r = SOCKETWINDOWSIZE;

                int rd = 0;

                Byte[] senddatas = new Byte[SOCKETWINDOWSIZE];

                fs.Seek(start, SeekOrigin.Begin);

                do

                {

                    r = start + length - fs.Position;

                    //fs.BeginRead(s,s,s,s,d) 以后使用的版本号。用以提高读取的效率                

                    if (r >= SOCKETWINDOWSIZE)

                        rd = fs.Read(senddatas, 0, SOCKETWINDOWSIZE);

                    else

                        rd = fs.Read(senddatas, 0, (int)r);

                    mSockSendData.Send(senddatas, 0, rd, SocketFlags.None);

                } while (fs.Position != start + length);



            }

            catch (SocketException e)

            {

                throw e;

            }

            catch (IOException e)

            {

                throw e;

            }

        }







        public Socket mSockSendData;//Notice: get from ClientSocketThread.s











        private string GetPathFileName(string filename)

        {

            const string strDefaultPage = "index.htm";

            const string strWWWRoot = "..\\..\\wwwroot\\";

            string strFileName = String.Copy(filename);

            if ("/" == strFileName)

                strFileName = strDefaultPage;

            return System.AppDomain.CurrentDomain.BaseDirectory + strWWWRoot + strFileName;

        }



        private void SendStr(Encoding coding, string strSend)//发送一个字符串

        {

            Byte[] sendchars = new Byte[512];

            sendchars = coding.GetBytes((strSend).ToCharArray());

            mSockSendData.Send(sendchars, 0, sendchars.Length, SocketFlags.None);

        }

    }

}



三,新建类ClientSocketThread。

using System;

using System.Net;

using System.Net.Sockets;

using System.Text;

using System.Threading;



namespace TestWeb

{

    class ClientSocketThread

    {

        public TcpListener tcpl;//Notice: get from SrvMain.tcpl

        private static Encoding ASCII = Encoding.ASCII;



        public void HandleThread()

        {

            Thread currentThread = Thread.CurrentThread;

            try

            {



                Socket s = tcpl.AcceptSocket();





                RequestProcessor aRequestProcessor = new RequestProcessor(); //Notice:

                aRequestProcessor.mSockSendData = s;//Notice: so that the processor can work





                const int BUFFERSIZE = 4096;//that's enough???

Byte[] readclientchar = new Byte[BUFFERSIZE];

                char[] sps = new Char[2] { '\r', '\n' };

                string[] RequestLines = new string[32];



                do

                {

                    //use BUFFERSIZE contral the receive data size to avoid the BufferOverflow attack

                    int rc = s.Receive(readclientchar, 0, BUFFERSIZE, SocketFlags.None);



                    string strReceive = ASCII.GetString(readclientchar, 0, rc);



                    RequestLines = strReceive.Split(sps);





                } while (aRequestProcessor.ParseRequestAndProcess(RequestLines));



                s.Close();

            }

            catch (SocketException)

            {



            }

        }





    }

}





四。主对话框中添加button,按键的对应函数加例如以下代码。

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;



using System.IO;

using System.Net;

using System.Net.Sockets;

using System.Threading;



namespace TestWeb

{

    public partial class Form1 : Form

    {

        public Form1()

        {

            InitializeComponent();

        }



        private void button1_Click(object sender, EventArgs e)

        {

              try

            {

                //启动监听程序                

                TcpListener tcpl;

                IPAddress LocalIP = Dns.Resolve("localhost").AddressList[0];

                tcpl = new TcpListener(LocalIP, 80); // listen on port 80

                tcpl.Start();

                         



               // int ThreadID = 0;

                while (true)

                {

                    while (!tcpl.Pending())

                    {

                        Thread.Sleep(100);

                    }



                    //启动接受线程

                    ClientSocketThread myThreadHandler = new ClientSocketThread();

                    myThreadHandler.tcpl = tcpl;//Notice: dont forget do this

                    ThreadStart myThreadStart = new ThreadStart(myThreadHandler.HandleThread);

                    Thread myWorkerThread = new Thread(myThreadStart);      

                    myWorkerThread.Start();

                }

            }

            catch (SocketException )

            {

           

            }

            catch (FormatException)

            {

               

            }

            catch (Exception )

            {

               

            }

            //  Console.Read();

       

        }

    }

}

五,启动TestWeb.exe,并单击主对话框上的button。在浏览器中输入:http://127.0.0.1/ 或http://127.0.0.1:80。

源代码下载:

http://download.csdn.net/detail/he_zhidan/8884733

C#建立最简单的web服务,无需IIS的更多相关文章

  1. nodejs创建一个简单的web服务

    这是一个突如其来的想法,毕竟做web服务的框架那么多,为什么要选择nodejs,因为玩前端时,偶尔想调用接口获取数据,而不想关注业务逻辑,只是想获取数据,使用java或者.net每次修改更新后还要打包 ...

  2. 使用python命令构建最简单的web服务

    可以使用python自带的包建立最简单的web服务器,使用方法: 1)切换到服务器的根目录下 2)输入命令: python -m SimpleHTTPServer 3)使用wget或者在浏览器访问测试 ...

  3. linux系统下开启一个简单的web服务

    linux 下开启一个简单的web服务: 首先需要linux下安装nodejs 然后创建一个test.js:   vi test.js var http =require("http&quo ...

  4. node创建一个简单的web服务

    本文将如何用node创建一个简单的web服务,过程也很简单呢~ 开始之前要先安装node.js 1.创建一个最简单的服务 // server.js const http = require('http ...

  5. Web服务器之iis,apache,tomcat三者之间的比较

    IIS-Apache-Tomcat的区别 IIS与Tomcat的区别 IIS是微软公司的Web服务器.主要支持ASP语言环境. Tomcat是Java Servlet 2.2和JavaServer P ...

  6. 用Python建立最简单的web服务器

    利用Python自带的包可以建立简单的web服务器.在DOS里cd到准备做服务器根目录的路径下,输入命令: python -m Web服务器模块 [端口号,默认8000] 例如: python -m ...

  7. [转] 用Python建立最简单的web服务器

    [From] http://www.cnblogs.com/xuxn/archive/2011/02/14/build-simple-web-server-with-python.html 利用Pyt ...

  8. 学习用node.js建立一个简单的web服务器

    一.建立简单的Web服务器涉及到Node.js的一些基本知识点: 1.请求模块 在Node.js中,系统提供了许多有用的模块(当然你也可以用JavaScript编写自己的模块,以后的章节我们将详细讲解 ...

  9. 基于gin框架搭建的一个简单的web服务

    刚把go编程基础知识学习完了,学习的时间很短,可能还有的没有完全吸收.不过还是在项目中发现知识,然后在去回顾已学的知识,现在利用gin这个web框架做一个简单的CRUD操作. 1.Go Web框架的技 ...

随机推荐

  1. 从零实现一个http服务器

    我始终觉得,天生的出身很重要,但后天的努力更加重要,所以如今的很多“科班”往往不如后天努力的“非科班”.所以,我们需要重新给“专业”和“专家”下一个定义:所谓专业,就是别人搞你不搞,这就是你的“专业” ...

  2. P2756 网络流解决二分图最大匹配

    P2756 飞行员配对方案问题 题目背景 第二次世界大战时期.. 题目描述 P2756 飞行员配对方案问题 英国皇家空军从沦陷国征募了大量外籍飞行员.由皇家空军派出的每一架飞机都需要配备在航行技能和语 ...

  3. CF633H Fibonacci-ish II

    题目描述 题解: 坑题搞了三天. 莫队+线段树. 还有一些和斐波那契数列有关的性质. 首先答案是$a_1f_1+a_2f_2+…+a_nf_n$, 考虑插进去一个元素对答案产生的影响. 比如插进去一个 ...

  4. 用python的Requests库模拟http请求

    一.先了解几个重要的http请求头或响应头信息 Request Headers: Host: 描述请求将被发送的目的地,包括,且仅仅包括域名和端口号. Origin: 说明请求从哪里发起的,包括,且仅 ...

  5. 剑指Offer(书):旋转数组的最小数字

    题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转, ...

  6. linux 文件三大特殊权限(SUID SGID SBIT)

    SGID(这个应该是文件共享里面最常用权限管理手段) 作用于目录或可执行程序,作用于目录代表在此目录创建的文件或目录,默认的属组继承此目录的属组.例如 我这个testgroup 没有设置SGID .我 ...

  7. SpringMVC的删除功能

    Dao层 package net.roseindia.dao; import java.util.Date; import java.util.List; import net.roseindia.m ...

  8. 七牛云成功通过 CMMI3 认证

    10 月 31 日,在上海七牛信息技术有限公司青岛会议室举行的 CMMI3 级认证结果发布会上,主任评估师王庆付老师和评估组向公司高层及参与评审的 EPG 成员及项目组成员郑重宣布:经过严格的现场审核 ...

  9. Codeforces Round #277 (Div. 2 Only)

    A:SwapSort http://codeforces.com/problemset/problem/489/A 题目大意:将一个序列排序,可以交换任意两个数字,但要求交换的次数不超过n,输出任意一 ...

  10. selenide01---截图

    1.junit:import com.codeborne.selenide.junit.ScreenShooter; @Rule public ScreenShooter makeScreenshot ...