-
08-11-2008, 11:16 AM #1Banned
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
Lập trình Winsock trong C# | Winsock programing with C#
Hôm nay sẽ không phải là chủ đề về Graphics nữa. ZC sẽ mở ra một chủ đề mới đó là về lập trình mạng (đây cũng là chủ đề mà ZC đã hứa sẽ viết cho nhóm Software của huynguyen mà tới hôm nay mới có thời gian rãnh để làm).
Hiện nay thì môi trường mạng đang phát triển rất nhanh và gần như sự trao đổi dữ liệu giữa các máy tính đang trở nên rất cần thiết.
Có khá nhiều giải pháp lập trình để làm việc với môi trường mạng như Remote, hay WebServices nhưng Winsock vẫn là những lý thuyết cơ bản nhất.
Điều duy nhất mà ZC mong muốn đó là sẽ hỗ trợ cho mọi người.
Mình sẽ cập nhật bài viết này sớm.View more random threads:
- Hướng dẫn cài đặt Low-Level Keyboard Hook trong C#
- Cần giải thích về đoạn mã giả (thuật toán tìm kiếm Fringe Search)
- Mọi người xem qua DashBoard mình mới làm, có gì xin mọi người góp ý
- Tô vẽ và chỉnh lại kích thước của form trong lập trình C#
- Help!!! Chủ đề về SQL !!!
- Mã hóa chuỗi bằng các kiểu mã hóa ký tự trong lập trình C#
- Xây dựng Danh sách liên kết trong C#
- Mong các bạn giúp đỡ thuật toán A* tìm nhiều đường đi từ 1 điểm đến 1 điểm
- Chia sẻ code dùng transaction một cách đơn giản và dễ code nhất. Có thể sử dụng trên 1 hoặc nhiều db
- Xin giúp đỡ về thuật toán làm tkb
-
09-11-2008, 05:17 PM #2Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
I. Dữ liệu truyền tải
Đầu tiên mình sẽ nói sơ qua về vấn đề dữ liệu được truyền tải trên môi trường mạng.
Dữ liệu ở cấp độ thấp nhất là bit. Cao hơn là byte và còn vài cấp cao hơn nữa. Nhưng byte được xem là chuẩn đề truyền dữ liệu. Do vậy trước khi chúng ta gửi hay nhận bất cứ dữ liệu gì thì bắc buộc ta phải đưa dữ liệu của đối tượng đó về đơn vị byte.
C# khác với C++ ở nhiều điểm. Và điểm khác rõ nhất là tất cả các kiểu dữ liệu của C# đều là đối tượng (object) Trong khi dữ liệu của C++ là các vùng nhớ trên bộ nhớ.
Do đó ở C# bạn không thể ép kiểu từ string thành byte như C++ chuyển WCHAR* thành char*.
Và chúng ta sẽ làm quen cách chuyển đổi này trên C#.
Hiện nay chúng ta có 3 bảng mã chính, ngoài ra còn nhiều nữa nhưng ít được sử dụng:
ASCII
- Bảng mã ASCII thì mỗi ký tự là 1 byte.
UTF8
- Bảng mã UTF8 thì trong 1 chuỗi string không hẵn các ký tự là 1 byte, có khi nó tới 2,3 byte tùy thuộc vào ký tự đó.
- Tức là những ký tự có trong mã ASCII thì nó chiếm 1 byte. Còn các ký tự đặc biệt như chữ 'ô' 'ê'... thì biểu diễn tới 2 hay 3 bytes tùy thuộc vào bảng mã.
UTF16 hay Unicode
- Bảng mã UTF16 thì sang hơn 1 chút. Các ký tự chiếm đều 2 bytes nên nó có thể biểu diễn mọi ngôn ngữ trên thế giới.
- UTF16 có 2 loại là UTF16-LE (Unicode chuẩn) và UTF16-BE.
- UTF16-BE (Big Endian) khác so với UTF16 (Little Endian) ở chỗ hoán đổi vị trí bytes trên 1 ký tự. Ví dụ :ký tự ở UTF16-LE có giá trị là 0xAABB thì UTF16-BE ký tự đó sẽ là là 0xBBAA</font>
+ UTF8 thì lại được sử dụng chính trên các giao thức như HTTP, SOAP vì nó tiết kiệm được dữ liệu.
+ ASCII khá cổ nhưng vẫn được sử dụng.
Trong C# kiểu char chiếm 2 bytes. Kiểu byte chiếm 1 byte. string là đối tượng của mảng char[] nên nó thể hiện chuỗi Unicode.
Vậy còn các kiểu như float, int32,... làm cách nào để chuyển thành byte[], giải pháp đặt ra là phải parse ( ToString() ) các kiểu này thành string rồi chuyển thành byte.
<font color="DarkRed">1. Chuyển dữ liệu thành BYTE
UTF16 thành ACSII
Mã:string examString = "Đây là chuỗi UTF16!!!";byte[] ascii= ASCIIEncoding.ASCII.GetBytes(examString);
Mã:string examString = "Đây là chuỗi UTF16!!!";byte[] utf8= ASCIIEncoding.UTF8.GetBytes(examString);
ASCII thành Unicode
Mã:string examString = "Đây là chuỗi UTF16!!!";byte[] ascii= ASCIIEncoding.ASCII.GetBytes(examString);// ASCII -> UNICODEstring result = Encoding.ASCII.GetString(utf8);
Mã:string examString = "Đây là chuỗi UTF16!!!";byte[] utf8= ASCIIEncoding.UTF8.GetBytes(examString);// UTF8 -> UNICODEstring result = Encoding.UTF8.GetString(utf8);
-
11-11-2008, 06:58 PM #3Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
II. Address
1. Địa chỉ IP</font>
Khi bạn gửi 1 bức thư, 1 điều cần thiết nhất là bạn phải có địa chỉ nơi nhận. Và trên Internet cũng vậy, mỗi host truy cập lên mạng thì sẽ có 1 IP để xác định chính nó.
Ip có 2 loại là V4 (4bytes) và V6 (6bytes).
Ta sẽ xét cấu trúc V4 vì nó đang được sử dụng.
1 địa chỉ IP thì nó chứa 2 thông tin:
+ NetID: Chỉ ra "đường mạng" (dựa vào đường mạng người ta lại phân lớp: A, B, C).
+ HostID: Là ID của máy tính trên đường mạng đó.
2 Host chỉ có thể trao đổi trực tiếp dữ liệu khi 2 host đó cùng trên 1 đường mạng. Còn nếu khác đường mạng thì nó phải đi qua các thiết bị chuyên dụng gọi là Router. ASDL Modem cũng chính là 1 router nhưng nó không phải là Router chuyên dụng. Nó chỉ có 1 chức năng của router chính là NAT (Network Address Translate - Chuyển đổi đường mạng).
Nếu muốn nói sâu về IP thì có thể mất cả 1 tut nữa. Mình sẽ nôn na như thế này.
Gửi bởi ZCoder87
- Vào Start -> Run -> cmd (enter)
- Sau đó gõ lệnh "tracert google.com.vn"
Bạn có thể xem thêm thông tin về IP ở Lập Trình Mạng Với Thư Viện Winsock trên VC++
a. Đối tượng IPAddress
<font color="Red">Namespace: using System.Net;
1 IP sẽ chiếm hết 4 bytes. Do đó có thể xem như kiểu long hoặc byte[4].
Để thiết lập 1 địa chỉ IP chúng ta có thể dùng cách sau:
Từ 1 mảng bytes[4]
Mã:// Thiet lap IP 203.162.4.190byte []dnsIP = {203,162,4,190};IPAddress ip = new IPAddress(dnsIP); Console.WriteLine(ip);
Mã:byte[] ipFromString(string ipString){ string[] byteString = ipString.Split(new char[] { '.' }); byte[] adr = new byte[4]; adr[0] = byte.Parse(byteString[0]); adr[1] = byte.Parse(byteString[1]); adr[2] = byte.Parse(byteString[2]); adr[3] = byte.Parse(byteString[3]); return adr;}
Mã:string ipString = "210.245.0.11"; IPAddress ip = new IPAddress(ipFromString(ipString));Console.WriteLine(ip);
-
13-11-2008, 04:06 PM #4Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
Đối tượng IPEndpoint
Đây là đối tượng mà nó bao gồm 2 thông tin chính là IP Host và cả Port.
Mã:try{ // Lấy danh sách IP congdongcviet.com IPAddress[] ipServer = Dns.GetHostAddresses("congdongcviet.com"); // Kết nối port 80 IPEndPoint server = new IPEndPoint(ipServer[0], 80); }catch (Exception){ Console.WriteLine("DNS Error");}
-
18-11-2008, 08:58 AM #5Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
Hôm nay mình sẽ đi vào phần chính...
I. CHƯƠNG TRÌNH CLIENT
1. TCP Client
a. Kết nối
.NET có hỗ trợ sẵn một đối tượng dành cho Client. Đó là lớp đối tượng TCPClient
Ví dụ như kết nối tới port 80 của Server congdongcviet.com:
Mã:IPAddress[] ipServer = Dns.GetHostAddresses("congdongcviet.com");IPEndPoint server = new IPEndPoint(ipServer[0], 80); // Ket noi toi serverTcpClient client = new TcpClient();client.Connect(server);
b. Truyền và nhận dữ liệu
Bản chất của truyền và nhận dữ liệu cũng như ghi và đọc 1 stream (NetworkStream)
Mã:NetworkStream htmlProtocol = client.GetStream(); // Thong tin headerstring header = String.Format("GET / HTTP/1.1 Host: {0} User-Agent:{1} ", "congdongcviet.com", "ZClient");byte[] byteHeader = ASCIIEncoding.ASCII.GetBytes(header); // {*} Gui du lieu cho ServerhtmlProtocol.Write(byteHeader,0,byteHeader.Length);
Mã:GET / HTTP/1.1 Host: congdongcviet.com User-Agent: ZClient
c. Nhận dữ liệu
NetworkStream có 2 cơ chế nhận dữ liệu rất cơ bản là:
- ReadByte() Nhận từng byte.
- Read() Nhận một lượng bytes nào đó.
Cách tốt nhất là mình ví dụ code, mình đã note code rồi:
Dưới đây là cách nhận từng byte một.
Mã:static void Connect(string domain){ try { // Phan giai ten mien: domain -> ip IPAddress[] ipServer = Dns.GetHostAddresses(domain); IPEndPoint server = new IPEndPoint(ipServer[0], 80); // Ket noi toi server TcpClient client = new TcpClient(); client.Connect(server); NetworkStream htmlProtocol = client.GetStream(); // Thong tin header string header = String.Format(" GET / HTTP/1.1 Host: {0}\ nUser-Agent:{1} ", domain, "ZClient"); byte[] byteHeader = ASCIIEncoding.ASCII.GetBytes(header); // {*} Gui du lieu cho Server htmlProtocol.Write(byteHeader, 0, byteHeader.Length); Console.WriteLine("Header from {0}", domain); // {*} Nhan du lieu tu server int nEndHeader = 0; while (nEndHeader != 4) { char b = (char)htmlProtocol.ReadByte(); Console.Write(b); // Khi nhan chuoi ky tu thi het Header if (b == ' ' || b == ' ') nEndHeader++; else nEndHeader = 0; } } catch (Exception e) { Console.WriteLine(e.Message); }}
Mã:Connect("google.com"); HTTP/1.1 301 Moved Permanently Location: http://www.google.com/ Content-Type: text/html; charset=UTF-8 Date: Tue, 18 Nov 2008 07:19:23 GMT Expires: Thu, 18 Dec 2008 07:19:23 GMT Cache-Control: public, max-age=2592000 Server: gws Content-Length: 219
Mã:Connect("congdongcviet.com"); HTTP/1.1 200 OK Content-Length: 14121 Content-Type: text/html Content-Location: http://congdongcviet.com/index.htm Last-Modified: Thu, 06 Nov 2008 04:32:07 GMT Accept-Ranges: bytes ETag: "a4ba69a0c83fc91:197e4" Server: Microsoft-IIS/6.0 X-Powered-By: ASP.NET Date: Tue, 18 Nov 2008 07:20:04 GMT
Mã:Connect("forums.congdongcviet.com"); HTTP/1.1 200 OK Date: Tue, 18 Nov 2008 07:25:56 GMT Server: Apache X-Powered-By: PHP/5.2.6 Cache-Control: private Pragma: private Set-Cookie: bbsessionhash=e72b5bfe86b49410e3492d3b26bcb904; path=/; HttpOnly Set-Cookie: bblastvisit=1226993156; expires=Wed, 18-Nov-2009 07:25:56 GMT; path=/ Set-Cookie: bblastactivity=0; expires=Wed, 18-Nov-2009 07:25:56 GMT; path=/ Transfer-Encoding: chunked Content-Type: text/html; charset=utf-8
-
30-12-2008, 06:51 PM #6Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
cho mình hỏi.nếu mình tăng nEndHeader != 4 lên 100 lần thì đọc được cả body.nhưng mà khi đọc hết nó lại lấy gia trị nuLL bây giờ phải làm sao để đọc hết thì nó thôi!
-
31-12-2008, 12:29 PM #7Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
nEndHeader == 4 có nghĩa là khi nó gặp dấu hiệu kết thúc Header là "2 lần xuống hàng" (
hay là
)
Còn phần Body thì mình chưa load. Định tiếp viết phần đó tiếp theo nhưng chưa có thời gian rãnh. Để dọc được body thì bạn có thể đọc 1 lúc 512 bytes chứ ko phải 1 byte nữa, Và read nhiều lần như thế để lấy hết nội dung body website, nếu hàm read trả về giá trị < 512 có nghĩa là kết thúc body.
Còn việc bạn tăng lên 100 có thể chương trình sẽ gặp exception
-
03-01-2009, 01:45 PM #8Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
Gửi bởi ZCoder87
Mã:IPAddress ip = IPAddress.Parse(hostname)
-
13-01-2009, 05:31 PM #9Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
Mình đã thử viết 1 chương trình chat được qua Lan, nhưng qua Wan thì không kết nối 2 máy đươc, lên mạng tìm hiểu thì phải cấu hình port forwarding trong router. Mình có một thắc mắc là down torrent cũng có kết nối trực tiếp giữa 2 máy, mà có cần chỉnh port trong router đâu?!?
-
01-05-2009, 10:50 AM #10Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
mình cũng làm bài tập lớn chát trong mạnglan, minh đã chát được nhiều máy client với với một máy sever, nhưng hiện tại mình muốn chát gữu các máy client với nhau thì làm sao, mình làm như yahooo có ôn không?
vấn đề nữa là mình muốn truyền file trong mạng lan thì truyển coa khác j không so với truyền file text có khác nhau j không
vd mình muốn truyền file wmv chẳng hạn
Bất chấp những lầm tưởng phổ quát, hồ hết những người có âm đạo đều khó lên đỉnh khi bị kích thích âm đạo. Tuy nhiên, điều đó không có tức thị nó không thể vui được! Việc xâm nhập vào âm đạo bằng...
Quý bà giải tỏa bằng việc kích...