程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#建立最簡單的web服務,無需IIS

C#建立最簡單的web服務,無需IIS

編輯:C#入門知識

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 + );
SendStr(coding, Date: );
SendStr(coding, Server: httpsrv/1.0 );
SendStr(coding, MIME-Version: 1.0 );
SendStr(coding, Content-Type: + fileType + );


strSend = Content-Length: + length.ToString();
SendStr(coding, strSend + );

//發送一個空行
SendStr(coding, );
}
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] { ' ', ' ' };
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)
{

}
}


}
}


四,主對話框中增加按鈕,按鍵的相應函數加如下代碼。
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,並單擊主對話框上的按鈕。在浏覽器中輸入:http://127.0.0.1/ 或http://127.0.0.1:80。


 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved