Mục tiêu: trình bày nguyên lý làm việc của máy chủ Web, Vận dụng các
giao thức để thực hiện kết nối với chương trình duyệt web và bảo mật thông tin
kết nối, dữ liệu.
Ta có thể hỏi lý do tại sao bạn nên phát triển một máy chủ trong NET khi
IIS là tự do có sẵn. Một máy chủ trong nhà phát triển có một số lợi thế, chẳng
hạn như sau đây:
+ Máy chủ Web có thể được cài đặt như một phần của một ứng dụng, mà
không đòi hỏingười sử dụng phải cài đặt IIS bằng tay từ đĩa CD cài đặt
Windows.
+ IIS sẽ không cài đặt trên Windows XP Home Edition, chiếm một phần đáng kể người dùng Windows
* Thực thi một máy chủ Web
Bắt đầu một mới Visual Studio. Dự án NET như bình thường. Vẽ hai
textbox, tbPath và tbPort, vào biểu mẫu, theo sau bằng một nút, btnStart, và một
hộp danh sáchtên là lbConnections, trong đó có xem nó vào danh sách. Tại trung tâm của một máy chủ HTTP là một máy chủ TCP, và bạn có thể nhận
thấy một trùng mã giữa các ví dụ này và máy chủ TCP trong chương
trước. Các máy chủ đã được đa luồng, vì vậy bước đầu tiên là khai báo một danh
public partial class Form1 : Form
{
private ArrayList alSockets; ……..
}
Thực thi-Path, mà trả về không chỉ con đường mà còn tên tập tin, và do đó
chúng tôi có thể cắt bỏ tất cả các ký tự sau khi người cuối cùng dấu gạch chéo ngược Mỗi máy chủ HTTP có một gốc rễ HTTP, mà là một đường dẫn đến một thư mục trên đĩa cứng của bạn mà từ đó các máy chủ sẽ lấy các trang Web. IIS
có một gốc HTTP mặc định C: \inetpub\wwwroot, trong trường hợp này, chúng ta sẽ sử dụng đường dẫntrong đó ứng dụng được lưu.Để có được đường dẫn ứng dụng, chúng ta có thể sử dụng ứng dụng. Thực thi-Path, mà trả về không chỉ con đường mà còn tên tập tin, và do đó chúng tôi có thể cắt bỏ tất cả các ký tự sau khi người cuối cùng dấu gạch chéo ngược.
private void Form1_Load(object sender, EventArgs e) {
tbPath.Text = Application.ExecutablePath; // trim off filename, to get the path
tbPath.Text = tbPath.Text.Substring(0, tbPath.Text.LastIndexOf("\\")); }
private void btnStart_Click(object sender, EventArgs e) {
alSockets = new ArrayList();
Thread thdListener = new Thread(new ThreadStart(listenerThread)); thdListener.Start();
}
public void listenerThread() {
int port = 0;
port = Convert.ToInt16(tbPort.Text);
TcpListener tcpListener = new TcpListener(port); tcpListener.Start();
while (true) {
Socket handlerSocket = tcpListener.AcceptSocket(); if (handlerSocket.Connected) { lbConnections.Items.Add(handlerSocket.RemoteEndPoint.ToString() + " connected."); lock (this) { alSockets.Add(handlerSocket); ThreadStart thdstHandler = new ThreadStart(handlerThread);
Thread thdHandler = new Thread(thdstHandler); thdHandler.Start();
} } } }
public void handlerThread() {
Socket handlerSocket = (Socket)alSockets[alSockets.Count - 1]; String streamData = "";
String filename = ""; String[] verbs;
StreamReader quickRead;
NetworkStream networkStream = new NetworkStream(handlerSocket); quickRead = new StreamReader(networkStream);
streamData = quickRead.ReadLine();
verbs = streamData.Split(" ".ToCharArray()); // Assume verbs[0]=GET
filename = verbs[1].Replace("/", "\\"); if (filename.IndexOf("?") != -1) {
// Trim of anything after a question mark (Querystring) filename = filename.Substring(0, filename.IndexOf("?")); }
if (filename.EndsWith("\\")) {
// Add a default page if not specified filename += "index.htm";
}
filename = tbPath.Text + filename;
FileStream fs = new FileStream(filename, FileMode.OpenOrCreate); fs.Seek(0, SeekOrigin.Begin);
byte[] fileContents = new byte[fs.Length]; fs.Read(fileContents, 0, (int)fs.Length); fs.Close();
// optional: modify fileContents to include HTTP header. handlerSocket.Send(fileContents);
lbConnections.Items.Add(filename); handlerSocket.Close();