• Nếu website sử dụng Basic authentication hay Digest authentication, bạn cần gửi kết hợp username và password, bằng cách tạo một đối tượng System.Net.. • Nếu website đòi hỏi chứng chỉ,
Trang 1• Nếu website sử dụng Basic authentication hay Digest authentication, bạn cần gửi kết
hợp username và password, bằng cách tạo một đối tượng System.Net NetworkCredential và gán nó vào thuộc tính WebRequest.Credentials
• Nếu website sử dụng Integrated Windows authentication, bạn thực hiện tương tự như
trên Bạn có thể lấy các thông tin đăng nhập của người dùng hiện hành từ đối tượng System.Net.CredentialCache
• Nếu website đòi hỏi chứng chỉ, bạn cần nạp chứng chỉ từ một file bằng lớp System.Security.Cryptography.X509Certificates.X509Certificate, và thêm nó vào tập hợp HttpWebRequest.ClientCertificates.
Dưới đây là đoạn mã ví dụ cho cả ba cách tiếp cận trên:
using System;
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class DownloadWithAuthentication {
private static void Main() {
string uriBasic, uriIntegrated, uriCertificate;
// Xác thực username và password với Basic authentication
WebRequest requestA = WebRequest.Create(uriBasic);
requestA.Credentials =
new NetworkCredential("userName", "password");
requestA.PreAuthenticate = true;
// Đăng nhập người dùng hiện hành với
// Integrated Windows authentication
WebRequest requestB = WebRequest.Create(uriIntegrated);
requestB.Credentials = CredentialCache.DefaultCredentials;
requestB.PreAuthenticate = true;
// Xác thực người dùng bằng chữ ký điện tử
HttpWebRequest requestC = (HttpWebRequest)
WebRequest.Create(uriCertificate);
X509Certificate cert =
X509Certificate.CreateFromCertFile(@"c:\user.cer");
Trang 2requestC.ClientCertificates.Add(cert);
// (Bây giờ bắt đầu lấy và xử lý đáp ứng.)
}
}
Nhớ rằng, nếu muốn sử dụng kiểu xác thực chứng chỉ, bạn phải nạp chứng chỉ
từ file Không có cách nào để tạo đối tượng X509Certificate từ một chứng chỉ trong kho chứng chỉ của máy tính.
4. Hi n th trang web trong ng d ng d a-trên-Windows Hi n th trang web trong ng d ng d a-trên-Windows ể ể ị ị ứ ứ ụ ụ ự ự
Bạn cần hiển thị một trang HTML (hay bất kỳ kiểu tài liệu nào mà Microsoft
Internet Explorer hỗ trợ) trong một ứng dụng dựa-trên-Windows.
Sử dụng điều kiểm ActiveX Web Browser (đi cùng với Internet Explorer).
.NET Framework không cung cấp điều kiểm nào dùng để dịch nội dung HTML Tuy nhiên, chức năng này lại rất cần thiết cho việc hiển thị một nội dung HTML cục bộ (kể cả những tài liệu HTML đóng gói theo định dạng file trợ giúp của Windows) cũng như các thông tin nào đó
từ web.
Để hiển thị một trang HTML, bạn có thể thêm một cửa sổ Internet Explorer vào ứng dụng dựa-trên-Windows Cửa sổ này không chỉ hỗ trợ HTML, mà còn hỗ trợ JavaScript, Microsoft
Visual Basic Scripting Edition (VBScript), ActiveX control, và rất nhiều plug-in khác, tùy
thuộc vào cấu hình hệ thống của bạn (có thể gồm cả Microsoft Word, Microsoft Excel, và
Adobe Acrobat Reader) Bạn còn có thể sử dụng điều kiểm Web Browser để duyệt một thư
mục trong ổ đĩa cục bộ, hay hiển thị các file trên một FTP (File Transfer Protocol) site.
Để thêm Web Browser vào một dự án trong Microsoft Visual Studio NET, bạn hãy nhắp phải vào hộp công cụ và chọn Add/Remove Items Sau đó, chọn thẻ COM Components, và chọn
Microsoft Web Browser (xem hình 11.2) Theo đó, điều kiểm Microsoft Web Browser sẽ được
thêm vào hộp công cụ Khi bạn thả điều kiểm này vào form, các Interop Assembly cần thiết sẽ
được tạo ra và thêm vào dự án của bạn.
Trang 3Hình 11.2 Chọn Microsoft Web Browser trong hộp thoại Customize Toolbox
Nếu không sử dụng Visual Studio NET, bạn cần tạo ra một vỏ bọc bằng tiện ích Type Library
Importer (Tlbimp.exe), sẽ được giải thích trong mục 15.6.
Khi sử dụng điều kiểm Web Browser, bạn thường cần các phương thức sau:
• Navigate (và Navigate2) Chuyển trang sang URL do bạn chỉ định.
• GoBack và GoForward Lái sang các trang trong danh sách history.
• GoHome Lái sang trang mặc định (home) được thiết lập trên máy tính hiện hành, và GoSearch Hiển thị trang tìm kiếm.
Người dùng có thể vào một trang mới bằng cách nhắp vào một liên kết nào đó trong trang
hiện hành (nếu nó tồn tại) Bạn có thể lấy URL hiện hành từ thuộc tính LocationURL và xác định điều kiểm vẫn còn xử lý trang đó hay không bằng cách kiểm tra thuộc tính Busy Ngoài
ra, bạn có thể phản ứng với nhiều sự kiện khác nhau.
Trang 4Hình 11.3 Sử dụng điều kiểm Web Browser
using System;
using System.Drawing;
using System.Windows.Forms;
public class WebBrowser : System.Windows.Forms.Form {
private AxSHDocVw.AxWebBrowser explorer;
private System.Windows.Forms.Button cmdBack;
private System.Windows.Forms.Button cmdHome;
private System.Windows.Forms.Button cmdForward;
// (Bỏ qua phần mã designer.)
Trang 5object nullObject = null;
object uri = "http://www.dvpub.com.vn";
explorer.Navigate2(ref uri, ref nullObject, ref nullObject,
ref nullObject, ref nullObject);
}
private void cmdHome_Click(object sender, System.EventArgs e) {
explorer.GoHome();
}
private void cmdForward_Click(object sender, System.EventArgs e) {
try {
explorer.GoForward();
} catch {
MessageBox.Show("Already on last page.");
}
}
private void cmdBack_Click(object sender, System.EventArgs e) {
try {
explorer.GoBack();
} catch {
MessageBox.Show("Already on first page.");
}
}
}
Hầu hết các phương thức của điều kiểm Web Browser đều yêu cầu một vài thông số Vì các phương thức này không được nạp chồng, và vì C# không hỗ trợ tham số tùy chọn, nên bạn
phải cung cấp giá trị cho mọi tham số Bạn không thể sử dụng tham chiếu null được, vì chúng
là các thông số ref Thay vào đó, bạn hãy tạo ra một biến đối tượng chứa tham chiếu null, sau đó cung cấp nó cho các thông số mà bạn không cần sử dụng Kỹ thuật này sẽ được mô tả chi tiết trong mục 15.8.
Trang 65. L y đ a ch IP c a máy tính hi n hành L y đ a ch IP c a máy tính hi n hành ấ ị ấ ị ỉ ỉ ủ ủ ệ ệ
Bạn cần lấy địa chỉ IP của máy tính hiện hành, có thể là để sử dụng sau này
trong mã lệnh networking.
Sử dụng phương thức GetHostName và GetHostByName của lớp System.Net.Dns.
Lớp Dns cung cấp các dịch vụ phân giải tên miền Bạn có thể gọi phương thức GetHostName để
lấy về tên host của máy tính hiện hành Sau đó, bạn có thể dịch tên này sang địa chỉ IP bằng
phương thức GetHostByName Đây là một ví dụ:
using System;
using System.Net;
public class GetIPAddress {
private static void Main() {
// Lấy tên host của máy tính hiện hành
string hostName = Dns.GetHostName();
// Lấy địa chỉ IP trùng khớp đầu tiên
string ipAddress =
Dns.GetHostByName(hostName).AddressList[0].ToString();
Console.WriteLine("Host name: " + hostName);
Console.WriteLine("IP address: " + ipAddress);
Console.ReadLine();
}
}
Phương thức GetHostByName trả về danh sách các địa chỉ IP có hiệu lực Trong rất nhiều trường hợp, danh sách này chỉ có một phần tử.
Khi sử dụng địa chỉ IP trong giao tiếp mạng, bạn có thể sử dụng địa chỉ
127.0.0.1 để chỉ đến máy tính hiện hành thay cho địa chỉ IP thực tế của nó.
Trang 76. Phân gi i tên mi n thành đ a ch IP Phân gi i tên mi n thành đ a ch IP ả ả ề ề ị ị ỉ ỉ
Bạn muốn xác định địa chỉ IP của một máy tính dựa vào tên miền của nó bằng
cách thực hiện một truy vấn Domain Name System (DNS)
Sử dụng phương thức GetHostByName của lớp System.Net.Dns với đối số là tên
miền.
Trên web, các địa chỉ IP có thể truy xuất công khai thường được ánh xạ đến tên miền để dễ
nhớ hơn Ví dụ, địa chỉ 207.171.185.16 được ánh xạ đến tên miền www.amazon.com Để xác
định địa chỉ IP khi có tên miền, máy tính cần liên lạc với một DNS-server.
Quá trình phân giải tên miền được thực hiện một cách trong suốt khi bạn sử dụng lớp System.Net.Dns Lớp này cho phép lấy địa chỉ IP của một tên miền bằng phương thức GetHostByName Dưới đây là đoạn mã trình bày cách lấy danh sách các địa chỉ IP được ánh xạ đến tên miền www.microsoft.com
using System;
using System.Net;
public class ResolveIP {
private static void Main() {
foreach (IPAddress ip in
Dns.GetHostByName("www.microsoft.com").AddressList) {
Console.Write(ip.AddressFamily.ToString() + ": ");
Console.WriteLine(ip.ToString());
}
Console.ReadLine();
}
}
Khi chạy đoạn mã trên, bạn sẽ thấy kết xuất như sau:
InterNetwork: 207.46.249.222
InterNetwork: 207.46.134.222
InterNetwork: 207.46.249.27
InterNetwork: 207.46.134.155
InterNetwork: 207.46.249.190
Trang 87. “Ping” m t đ a ch IP “Ping” m t đ a ch IP ộ ị ộ ị ỉ ỉ
Bạn muốn kiểm tra một máy tính có online hay không và đo thời gian đáp ứng
(response time) của nó.
Gửi một thông điệp “ping” Thông điệp này được gửi bằng giao thức Internet
Control Message Protocol (ICMP) với một raw-socket.
Một thông điệp “ping” giao tiếp với một thiết bị tại một địa chỉ IP cụ thể, gửi một thông điệp
thử nghiệm, và yêu cầu thiết bị này đáp ứng lại Để đo thời gian kết nối giữa hai máy tính, bạn
có thể đo thời gian cho một đáp ứng.
Mặc dù thông điệp “ping” đơn giản hơn các kiểu giao tiếp khác, nhưng hiện thực một tiện ích
“ping” trong NET đòi hỏi một lượng lớn mã lệnh networking mức-thấp và phức tạp Thư viện lớp NET không có sẵn giải pháp nào—thay vào đó, bạn phải sử dụng raw-socket và một số
mã lệnh cực kỳ dài.
Tuy nhiên, đã có ít nhất một nhà phát triển giải quyết được vấn đề “ping” Dưới đây là mã
lệnh do Lance Olson, một nhà phát triển của Microsoft, cung cấp Mã lệnh này cho phép
“ping” một host bằng tên hay địa chỉ IP và đo lượng mili-giây cho một đáp ứng.
using System;
using System.Net;
using System.Net.Sockets;
public class Pinger {
public static int GetPingTime(string host) {
int dwStart = 0, dwStop = 0;
// Tạo một raw-socket
Socket socket = new Socket(AddressFamily.InterNetwork,
SocketType.Raw, ProtocolType.Icmp);
// Lấy IPEndPoint của server, và chuyển nó thành EndPoint
IPHostEntry serverHE = Dns.GetHostByName(host);
IPEndPoint ipepServer =
new IPEndPoint(serverHE.AddressList[0], 0);
EndPoint epServer = (ipepServer);
Trang 9IPHostEntry fromHE = Dns.GetHostByName(Dns.GetHostName());
IPEndPoint ipEndPointFrom =
new IPEndPoint(fromHE.AddressList[0], 0);
EndPoint EndPointFrom = (ipEndPointFrom);
// Tạo packet
int PacketSize = 0;
IcmpPacket packet = new IcmpPacket();
for (int j = 0; j < 1; j++) {
packet.Type = ICMP_ECHO;
packet.SubCode = 0;
packet.CheckSum = UInt16.Parse("0");
packet.Identifier = UInt16.Parse("45");
packet.SequenceNumber = UInt16.Parse("0");
int PingData = 32;
packet.Data = new Byte[PingData];
for (int i = 0; i < PingData; i++)
packet.Data[i] = (byte)'#';
PacketSize = PingData + 8;
Byte [] icmp_pkt_buffer = new Byte [PacketSize];
int index = 0;
index = Serialize(packet,
icmp_pkt_buffer, PacketSize, PingData);
// Tính checksum cho packet
double double_length = Convert.ToDouble(index);
double dtemp = Math.Ceiling(double_length / 2);
int cksum_buffer_length = Convert.ToInt32(dtemp);
UInt16[] cksum_buffer = new UInt16[cksum_buffer_length];
int icmp_header_buffer_index = 0;
for (int i = 0; i < cksum_buffer_length; i++) {
Trang 10cksum_buffer[i] = BitConverter.ToUInt16(icmp_pkt_buffer, icmp_header_buffer_index);
icmp_header_buffer_index += 2;
}
UInt16 u_cksum = checksum(cksum_buffer, cksum_buffer_length); packet.CheckSum = u_cksum;
// Tuần tự hóa packet
byte[] sendbuf = new byte[PacketSize];
index = Serialize(packet, sendbuf, PacketSize, PingData);
// Bắt đầu tính giờ
dwStart = System.Environment.TickCount;
socket.SendTo(sendbuf, PacketSize, 0, epServer);
// Nhận đáp ứng, và ngừng tính giờ
byte[] ReceiveBuffer = new byte[256];
socket.ReceiveFrom(ReceiveBuffer, 256, 0, ref EndPointFrom); dwStop = System.Environment.TickCount - dwStart;
}
// Dọn dẹp và trả về thời gian "ping" (tính theo giây)
socket.Close();
return (int)dwStop;
}
private static int Serialize(IcmpPacket packet, byte[] buffer,
int packetSize, int pingData) {
// (Bỏ qua phương thức private dùng để tuần tự hóa packet.) }
private static UInt16 checksum(UInt16[] buffer, int size) {