C#建立最简单的web服务,无需IIS
软件架构师何志丹
本程序仅仅是入门级程序。所以不考虑
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。
源代码下载:
C#建立最简单的web服务,无需IIS的更多相关文章
- nodejs创建一个简单的web服务
这是一个突如其来的想法,毕竟做web服务的框架那么多,为什么要选择nodejs,因为玩前端时,偶尔想调用接口获取数据,而不想关注业务逻辑,只是想获取数据,使用java或者.net每次修改更新后还要打包 ...
- 使用python命令构建最简单的web服务
可以使用python自带的包建立最简单的web服务器,使用方法: 1)切换到服务器的根目录下 2)输入命令: python -m SimpleHTTPServer 3)使用wget或者在浏览器访问测试 ...
- linux系统下开启一个简单的web服务
linux 下开启一个简单的web服务: 首先需要linux下安装nodejs 然后创建一个test.js: vi test.js var http =require("http&quo ...
- node创建一个简单的web服务
本文将如何用node创建一个简单的web服务,过程也很简单呢~ 开始之前要先安装node.js 1.创建一个最简单的服务 // server.js const http = require('http ...
- Web服务器之iis,apache,tomcat三者之间的比较
IIS-Apache-Tomcat的区别 IIS与Tomcat的区别 IIS是微软公司的Web服务器.主要支持ASP语言环境. Tomcat是Java Servlet 2.2和JavaServer P ...
- 用Python建立最简单的web服务器
利用Python自带的包可以建立简单的web服务器.在DOS里cd到准备做服务器根目录的路径下,输入命令: python -m Web服务器模块 [端口号,默认8000] 例如: python -m ...
- [转] 用Python建立最简单的web服务器
[From] http://www.cnblogs.com/xuxn/archive/2011/02/14/build-simple-web-server-with-python.html 利用Pyt ...
- 学习用node.js建立一个简单的web服务器
一.建立简单的Web服务器涉及到Node.js的一些基本知识点: 1.请求模块 在Node.js中,系统提供了许多有用的模块(当然你也可以用JavaScript编写自己的模块,以后的章节我们将详细讲解 ...
- 基于gin框架搭建的一个简单的web服务
刚把go编程基础知识学习完了,学习的时间很短,可能还有的没有完全吸收.不过还是在项目中发现知识,然后在去回顾已学的知识,现在利用gin这个web框架做一个简单的CRUD操作. 1.Go Web框架的技 ...
随机推荐
- 条款15:在资源管理类中提供对原始资源的访问(Provide access to raw resources in resource-managing classes)
NOTE: 1.APIs往往要求访问原始资源(raw resources),所以每一个RAII class应该提供一个“取得其所管理之资源”的办法. 2.对原始资源的访问可能经由显示转换或隐式转换.一 ...
- tornado框架基础02-输入和输出
01 输出 write bytes类型 class IndexHandler(tornado.web.RequestHandler): def get(self): self.write(b'Torn ...
- pwnable.kr cmd2之write up
来看一下源代码: #include <stdio.h> #include <string.h> int filter(char* cmd){ ; r += strstr(cmd ...
- STL中set求交集、并集、差集的方法
并集(http://zh.cppreference.com/w/cpp/algorithm/set_union) 交集(http://zh.cppreference.com/w/cpp/algorit ...
- 最近的一些JAVA基础知识
1,关于判断两个值是否相等 equal 和==是有区别到 2,判断一个数组集合 List是否为空 这个不能用"==null或者equal"要用isEmpty() , 对于不等于加一 ...
- Oracle の ty_str_split + MySQL の proc_split
oracle实现字符串分割 功能描述:用指定分隔符切割输入的字符串,返回一维数组,每个数组元素为一个子串. ); CREATE OR REPLACE FUNCTION fn_split (p_str ...
- C#静态构造函数和非静态构造函数
// 使用静态构造函数时,需要注意几点 //1. 一个类中,最多只能有一个静态构造函数,不允许静态构造函数的重载: //2. 不能加任何访问修饰符(public/private/internale等) ...
- HDU1754-I Hate It,线段数水题~~2016.4.11
I Hate It ...
- bzoj 2337 高斯消元+概率DP
题目大意: 每条路径上有一个距离值,从1走到N可以得到一个所有经过路径的异或和,求这个异或和的数学期望 这道题直接去求数学期望的DP会导致很难列出多元方程组 我们可以考虑每一个二进制位从1走到N的平均 ...
- 【2017多校训练2+计算几何+板】HDU 6055 Regular polygon
http://acm.hdu.edu.cn/showproblem.php?pid=6055 [题意] 给定n个格点,问有多少个正多边形 [思路] 因为是格点,只可能是正方形 枚举正方形的对角线,因为 ...