Mở đầu 1.1 Lý do chọn đề tài: Hiện nay, mạng Lan đã có những tiến bộ vƣợt bậc và ngày càng phổ biến hơn trong đồi sống sinh hoat. Điều này làm cho nhu cầu liên lạc và trao đổi thông tin thông qua mạng Lan ngày càng lớn hơn. Chính vì vậy, chƣơng trình Chat trên mạng Lan đƣợc xây dựng để đáp ứng phần nào những nhu cầu cấp thiết đó.2 Mục đích của đề tài: Xây dựng chƣơng trình Chat hoạt động trong mạng Lan với các chức năng cơ bản nhƣ: gởi tin nhắn, tạo một nhóm Chat và lƣu thông tin bạn bè.3 Đối tƣợng và phạm vi nghiên cứu 1.1 Đối tƣợng nghiên cứu Tìm hiểu đƣợc cơ chế hoạt động của Socket và Thread trong .NET Framwork từ đó viết ứng dụng Chat trong mạng Lan.2 Phạm vi nghiên cứu Chƣơng trình Chat đƣợc xây dựng với khả năng Chat bằng văn bản giữa các User, thành lập các nhóm Chat thông qua sự điều khiển của một Server trong mạng Lan. Trang 8 Chƣơng 2: KIẾN THỨC ỨNG DỤNG 2.1 Sơ lƣợc về lập trình Socket: 2.1 Khái niệm Địa chỉ và cổng (Address & Port) Nguyên lý: Trong một máy có rất nhiều ứng dụng muốn trao đối với các ứng dụng khác thông qua mạng (ví dụ trên có 2 ứng dụng trong máy A muốn trao đổi với với 2 ứng dụng trên máy B).
Mỗi máy tính chỉ có duy nhất một đƣờng truyền dữ liệu (để gửi và nhận). Vấn đề : Rất có thể xảy ra "nhầm lẫn" khi dữ liệu từ máy A gửi đến máy B thì không biết là dữ liệu đó gửi cho ứng dụng nào trên máy B? Giải quyết: Mỗi ứng dụng trên máy B sẽ đƣợc gán một số hiệu (mà ta vẫn quen gọi là cổng Port), số hiệu cổng này từ 1. Khi ứng dụng trên máy A muốn gửi cho ứng dụng nào trên máy B thì chỉ việc điền thêm số hiệu cổng (vào trƣờng RemotePort) vào gói tin cần gửi. Trên máy B, các ứng dụng sẽ việc kiểm tra giá trị cổng trên mỗi gói tin xem có trùng với số hiệu cổng của mình (đã đƣợc gán – chính là giá trị Localport) hay không? Nếu bằng thì xử lý, còn trái lại thì không làm gì.
Như vậy: Khi cần trao đổi dữ liệu cho nhau thì hai ứng dụng cần phải biết thông tin tối thiểu là địa chỉ (Address) và số hiệu cổng (Port) của ứng dụng kia.2 Lớp IPAddress Trên Internet mỗi một trạm (có thể là máy tính, máy in, thiết bị …) đều có một định danh duy nhất, định danh đó thƣờng đƣợc gọi là một địa chỉ (Address). Địa chỉ trên Internet là một tập hợp gồm 4 con số có giá trị từ 0-255 và cách nhau bởi dấu chấm. Để thể hiện địa chỉ này, ngƣời ta có thể viết dƣới các dạng sau: Tên : Ví dụ May01, Server, …. Trang 9 Địa chỉ IP nhƣng đặt trong một xâu: "192.1" Đặt trong một mảng 4 byte, mỗi byte chứa một số từ 0-255.
Ví dụ để biểu diễn địa chỉ 192.1 với khai báo “byte[] DiaChi = new byte[4];”, ta có thể viết: DiaChi(0) = 192; DiaChi(1) = 168; DiaChi(2) = 1; DiaChi(3) = 1; Hoặc cũng có thể là một số (long), có độ dài 4 byte. Ví dụ, với địa chỉ 192.1 ở trên thì giá trị đó sẽ là: 16885952 (đây là số ở hệ thập phân khi xếp liền 4 byte ở trên lại với nhau 00000001 00000001 10101000 11000000 1 (Byte 0) 1 168 192 (Byte 3) Nhƣ vậy, để đổi một địa chỉ chuẩn ra dạng số ta chỉ việc tính toán cho từng thành phần. Ví dụ: Đổi địa chỉ 192.2 ra số, ta tính nhƣ sau : 2 * 256 ^ 3 + 1* 256 ^ 2 + 168 * 256 ^ 1 + 192 * 256 ^ 0 Trong .NET, IPAddress là một lớp dùng để mô tả địa chỉ này. Đây là lớp rất cơ bản đƣợc sử dụng khi chúng ta thao tác (truyền) vào các lớp nhƣ IPEndpoint, UDP, TCP, Socket … Bảng 2-1: Các thành phần của lớp IpAddress Thành viên Static Mô tả Any Cung cấp một địa chỉ IP (thƣờng là 0.0) để chỉ ra rằng Server phải lắng nghe các hoạt động của Client trên tất cả các Card mạng (sử dụng khi xây dựng Server).
Thuộc tính này chỉ đọc. Broadcast Cung cấp một địa chỉ IP quảng bá (Broadcast, thƣờng là 255.255), ở dạng số long. Loopback Trả về một địa chỉ IP lặp (IP Loopback, ví dụ 127. AddressFamily Trả về họ địa chỉ của địa chỉ IP hiện hành.
Nếu địa chỉ Trang 10 ở dạng IPv4 thì kết quả là Internetwork, và InternetworkV6 nếu là địa chỉ IPv6. Phƣơng thức Mô tả IPAddress(Int64) Tạo địa chỉ IP từ một số long. IPAddress(Byte[]) Tạo địa chỉ IP từ một mảng Byte. GetAddressByte () Chuyển địa chỉ thành mảng Byte.
HostToNetworkOrder() Đảo thứ tự Byte của một số cho đúng với thứ tự Byte trong địa chỉ IPAddress. IsLoopback() Cho biết địa chỉ có phải là địa chỉ lặp hay không? Ví dụ 1: Kiểm tra xem 192.300 có phải là địa chỉ IP hợp lệ không private void KiemTra() { String Ip1 = "127.3 Lớp IPEndpoint Trong mạng, để hai trạm có thể trao đổi thông tin đƣợc với nhau thì chúng cần phải biết đƣợc địa chỉ (IP) của nhau và số hiệu cổng mà hai bên dùng để trao đổi thông tin. Lớp IPAddress mới chỉ cung cấp cho ta một vế là địa chỉ IP (IPAddress), nhƣ vậy vẫn còn thiếu vế thứ hai là số hiệu cổng (Port number). Nhƣ vậy, lớp IPEndpoint chính là lớp chứa đựng cả IPAddress và Port number.
Đối tƣợng IPEndpoint sẽ đƣợc dùng sau này để truyền trực tiếp cho các đối tƣợng UDP, TCP… Bảng 2-2: Các thành viên của lớp IpEndPoint Phƣơng thức khởi tạo Mô tả IPEndPoint(Int64, Int32) Tạo một đối tƣợng mới của lớp IPEndPoint, tham số truyền vào là địa chỉ IP (ở dạng số) và cổng sẽ dùng để giao tiếp. IPEndPoint(IPAddress, Tạo một đối tƣợng mới của lớp IPEndPoint, Int32) Tham số truyền vào là một địa chỉ IPAddress và số hiệu cổng dùng để giao tiếp. Thuộc tính Mô tả Address Trả về hoặc thiết lập địa chỉ IP cho Endpoint (trả về một đối tƣợng IPAddress). AddressFamily Lấy về loại giao thức mà Endpoint này đang sử dụng.
Port Lấy hoặc gán số hiệu cổng của Endpoint. Phƣơng thức Mô tả Create() Tạo một Endpoint từ một địa chỉ socket (socket address). ToString() Trả về địa chỉ IP và số hiệu cổng theo khuôn dạng địa chỉ: cổng.4 Lớp UDP Giao thức UDP (User Datagram Protocol hay User Define Protocol) là một giao thức phi kết nối (connectionless) có nghĩa là một bên có thể gửi dữ liệu cho bên kia mà không cần biết là bên đó đã sẵn sàng hay chƣa? (Nói cách khác là không cần thiết lập kết nối giữa hai bên khi tiến hành trao đổi thông tin). Giao thức này không tin cậy bằng giao thức TCP nhƣng tốc độ lại nhanh và dễ cài đặt.
Ngoài ra, với giao thức UDP ta còn có thể gửi các gói tin quảng bá (Broadcast) cho đồng thời nhiều máy.NET, lớp UDPClient (nằm trong namesapce System.Sockets) đóng gói các chức năng của giao thức UDP. Trang 13 Bảng 2-3: Các thành viên của lớp UDPClient Phƣơng thức khởi tạo Mô tả UdpClient () Tạo một đối tƣợng (thể hiện) mới của lớp UDPClient. UdpClient (AddressFamily) Tạo một đối tƣợng (thể hiện) mới của lớp UDPClient. Thuộc một dòng địa chỉ (AddressFamily) đƣợc chỉ định.
UdpClient (Int32) Tạo một UdpClient và gắn (bind) một cổng cho nó. UdpClient(Int32, Tạo một UdpClient và gán số hiệu cổng, AddressFamily) AddressFamily UdpClient(String, Int32) Tạo một UdpClient và thiết lập với một trạm từ xa mặc định. Phƣơng thức Mô tả BeginReceive() Nhận dữ liệu Không đồng bộ từ máy ở xa. BeginSend() Gửi không đồng bộ dữ liệu tới máy ở xa Close() Đóng kết nối.
Connect() Thiết lập một Default remote host. EndReceive() Kết thúc nhận dữ liệu không đồng bộ ở trên EndSend() Kết thúc việc gửi dữ liệu không đồng bộ ở trên Receive (ref IPEndPoint) Nhận dữ liệu (đồng bộ) do máy ở xa gửi. (Đồng bộ có nghĩa là các lệnh ngay sau lệnh Receive chỉ đƣợc thực thi nếu Receive đã nhận đƣợc dữ liệu về. Còn nếu nó chƣa nhận đƣợc – dù chỉ một chút – thì nó vẫn cứ chờ (blocking)) Send() Gửi dữ liệu (đồng bộ) cho máy ở xa.5 Lớp TCP (TCPClient) Mục đích của lớp UDPClient ở trên là dùng cho lập trình với giao thức UDP, với giao thức này thì hai bên không cần phải thiết lập kết nối trƣớc khi gửi do vậy mức độ tin cậy không cao.
Để đảm bảo độ tin cậy trong các ứng dụng mạng, ngƣời ta còn dùng một giao thức khác, gọi là giao thức có kết nối : TCP (Transport Control Protocol). Trên Internet chủ yếu là dùng loại giao thức này, ví dụ nhƣ Telnet, HTTP, SMTP, POP3… Để lập trình theo giao thức TCP, MS.NET cung cấp hai lớp có tên là TCPClient và TCPListener. Trang 15 Bảng 2-4: Các thành phần của lớp TcpClient Phƣơng thức khởi tạo Mô tả TcpClient() Tạo một đối tƣợng TcpClient. Chƣa đặt thông số gì.
TcpClient(IPEndPoint) Tạo một TcpClient và gắn cho nó một EndPoint cục bộ. (Gán địa chỉ máy cục bộ và số hiệu cổng để sử dụng trao đổi thông tin về sau) TcpClient(String,Int32) Tạo một đối tƣợng TcpClient và kết nối đến một máy có địa chỉ và số hiệu cổng đƣợc truyền vào. RemoteHost có thể là địa chỉ IP chuẩn hoặc tên máy. Các thuộc tính Mô tả Available Cho biết số byte đã nhận về từ mạng và có sẵn để đọc.
Client Trả về Socket ứng với TCPClient hiện hành. Connected Trạng thái cho biết đã kết nối đƣợc đến Server hay chƣa? Các hàm thành phần Mô tả Close() Giải phóng đối tƣợng TcpClient nhƣng không đóng kết nối. Connect(RemoteHost, Kết nối đến một máy TCP khác có Tên và số hiệu cổng. RemotePort) GetStream() Trả về NetworkStream để từ đó giúp ta gửi hay nhận dữ liệu.
Khi đã gắn vào StreamReader và StreamWriter rồi thì ta có thể gửi và nhận dữ liệu thông qua các phƣơng thức Readline, writeline tƣơng ứng của các lớp này. Từ các thành viên của lớp TcpClient ở trên ta thấy rằng, việc kết nối và thực hiện gửi nhận rất đơn giản. Theo các trình tự sau: Trang 16 Bƣớc 1: Tạo một đối tƣợng TcpClient. Bƣớc 2: Kết nối đến máy chủ (Server) dùng phƣơng thức Connect.
Bƣớc 3: Tạo 2 đối tƣợng StreamReader (Receive)và StreamWriter (Send) và "nối" với GetStream của cpPClient. Bƣớc 4: Dùng đối tƣợng StreamWriter.Writeline/Write vừa tạo ở trên để gửi dữ liệu đi. Dùng đối tƣợng StreamReader.Readline/Read vừa tạo ở trên để đọc dữ liệu về. Bƣớc 5: Đóng kết nối.
Nếu muốn gửi/nhận dữ liệu ở mức byte (nhị phân) thì dùng NetworkStream.6 Lớp TcpListener TCPListerner là một lớp cho phép ngƣời lập trình có thể xây dựng các ứng dụng Server (Ví dụ nhƣ SMTP Server, FTP Server, DNS Server, POP3 Server hay server tự định nghĩa ….