C#創(chuàng)建一個小型Web Server(Socket實現(xiàn))
要實現(xiàn)了Web Server,通過以下幾句代碼瀏覽器訪問就可以獲得訪問的數(shù)據(jù)。
Socket socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socketWatch.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 81));
socketWatch.Listen(20); // 參數(shù)表示最多可容納的等待接受的傳入連接數(shù),不包含已經(jīng)建立連接的。
Thread thread = new Thread(delegate(object obj)
{
Socket socketListen = (Socket)obj;
while (true)
{
Socket socket = socketListen.Accept();
byte[] data = new byte[1024 * 1024 * 4]; // 瀏覽器發(fā)來的數(shù)據(jù),限定為 4K。
int length = socket.Receive(data, 0, data.Length, SocketFlags.None);
socket.Send(Encoding.UTF8.GetBytes("歡迎訪問 www.cftea.com\r\n" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")));
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
});
thread.IsBackground = true;
thread.Start(socketWatch);
但以上只是原理,實際會很復(fù)雜,不過就算我們要做簡單的 Web Server,還是需要解決兩個問題:
一、輸出 HTTP 頭
byte[] body = Encoding.UTF8.GetBytes("歡迎訪問 www.cftea.com\r\n" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
byte[] head = Encoding.UTF8.GetBytes(@"HTTP/1.1 200 OK
Content-Length: " + body.Length + @"
Content-Type: text/plain
Date: " + string.Format("{0:R}", DateTime.Now) + @"
Server: Cftea Web Server
");
socket.Send(head);
socket.Send(body);
只要有特定的格式,就會被瀏覽器當(dāng)作 HTTP 頭對待。HTTP 頭的格式為:
- 第一行:HTTP/1.x + 空格 + 狀態(tài)碼 + 空格 + 描述
- 中間行:名稱 + 冒號 + 空格(也可以省略) + 值
- 最后行:空行
格式一定要正確,否則影響瀏覽器對 HTTP 頭和 HTTP 體的識別。
二、請求 HTTP 頭
到目前為止,我們還不知道瀏覽器中輸入的 URL 是什么呢。請求的 HTTP 頭也是有特定格式的,我們只需要將其獲取出來,進(jìn)行拆解,就可以獲取 URL 了。
拆解不是難事,我們說一說如何獲取吧。前面的 data、length 不是一直沒用么?如下:
string requestText = Encoding.UTF8.GetString(data, 0, length);
完整代碼
Socket socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socketWatch.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 81));
socketWatch.Listen(20); // 參數(shù)表示最多可容納的等待接受的傳入連接數(shù),不包含已經(jīng)建立連接的。
Thread thread = new Thread(delegate(object obj)
{
Socket socketListen = (Socket)obj;
while (true)
{
using (Socket socket = socketListen.Accept())
{
byte[] data = new byte[1024 * 1024 * 4]; // 瀏覽器發(fā)來的數(shù)據(jù)
int length = socket.Receive(data, 0, data.Length, SocketFlags.None);
if (length > 0)
{
string requestText = Encoding.UTF8.GetString(data, 0, length);
byte[] body = Encoding.UTF8.GetBytes(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
byte[] head = Encoding.UTF8.GetBytes(@"HTTP/1.1 200 OK
Content-Length: " + body.Length + @"
Content-Type: text/plain
Date: " + string.Format("{0:R}", DateTime.Now) + @"
Server: Cftea Web Server
");
socket.Send(head);
socket.Send(body);
}
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
}
});
thread.IsBackground = true;
thread.Start(socketWatch);
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流。
- C#使用SqlServer作為日志數(shù)據(jù)庫的設(shè)計與實現(xiàn)
- SQL Server存儲過程在C#中調(diào)用的簡單實現(xiàn)方法
- C#連接SQL Server數(shù)據(jù)庫的實例講解
- C#使用SqlConnection連接到SQL Server的代碼示例
- C# Ado.net實現(xiàn)讀取SQLServer數(shù)據(jù)庫存儲過程列表及參數(shù)信息示例
- C#連接SQL Server的實現(xiàn)方法
- C#實現(xiàn)連接SQL Server2012數(shù)據(jù)庫并執(zhí)行SQL語句的方法
- 基于C#動手實現(xiàn)網(wǎng)絡(luò)服務(wù)器Web Server
- C#連接到sql server2008數(shù)據(jù)庫的實例代碼
- C#實現(xiàn)的sqlserver操作類實例
- C#實現(xiàn)Excel表數(shù)據(jù)導(dǎo)入Sql Server數(shù)據(jù)庫中的方法
- C#實現(xiàn) Server-sent Events的步驟
相關(guān)文章
C#切換鼠標(biāo)左右鍵習(xí)慣無需控制面板中修改
本人一直喜歡左手使用鼠標(biāo),偶爾同事會臨時操作一下,因為他的習(xí)慣是右手,還得在控制面板里進(jìn)行更改,太麻煩了所以就編寫一個控制臺程序,雙擊一下即可切換左右鍵,熱愛懶人的你可不要錯過了哈2013-02-02

