Tìm hiểu và xây dưng mô hình ứng dụng Client/Server
1. GIỚI THIỆU MẠNG MÁY TÍNH Mạng máy tính hay hệ thống mạng (tiếng Anh: computer network hay network system), được thiết lập khi có từ 2 máy vi tính trở lên kết nối với nhau để chia sẻ tài nguyên: máy in, máy fax, tệp tin, dữ liệu... Một máy tính được gọi là tự hoạt (autonomous) nếu nó có thể ...
1. GIỚI THIỆU MẠNG MÁY TÍNH
Mạng máy tính hay hệ thống mạng (tiếng Anh: computer network hay network system), được thiết lập khi có từ 2 máy vi tính trở lên kết nối với nhau để chia sẻ tài nguyên: máy in, máy fax, tệp tin, dữ liệu... Một máy tính được gọi là tự hoạt (autonomous) nếu nó có thể khởi động, vận hành các phần mềm đã cài đặt và tắt máy mà không cần phải có sự điều khiển hay chi phối bởi một máy tính khác. Các thành phần của mạng có thể bao gồm: Các hệ thống đầu cuối (end system) kết nối với nhau tạo thành mạng, có thể là các máy tính hoặc các thiết bị khác. Nói chung hiện nay ngày càng nhiều các loại thiết bị có khả năng kết nối vào mạng máy tính như điện thoại di động, PDA, tivi,... Môi trường truyền (media) mà các thao tác truyền thông được thực hiện qua đó. Môi trường truyền có thể là các loại dây dẫn (dây cáp), sóng điện từ (đối với các mạng không dây). Giao thức truyền thông (protocol) là các quy tắc quy định cách trao đổi dữ liệu giữa các thực thể.
2. CÁC KIẾN THỨC CƠ BẢN VỀ MẠNG MÁY TÍNH
2.1. Mô hình 7 tầng OSI
Mô hình kết nối hệ thống mở được Tổ chức quốc tế chuẩn hóa ISO (International Organizaiton for Standardization) đưa ra nhằm cung cấp một mô hình chuẩn cho các nhà sản xuất và cung cấp sản phẩm viễn thông áp dụng theo để phát triển các sản phẩm viễn thông. Ý tưởng mô hình hóa được tạo ra còn nhằm hổ trợ cho việc kết nối giữa các hệ thống và modun hóa các thành phần phục vụ viễn thông. 2.1.1. Chức năng của mô hình OSI:
- Cung cấp kiến thức về hoạt động của kết nối liên mạng.
- Đưa ra trình tự công việc để thiết lập và thực hiện một giao thức cho kết nối các thiết bị trên mạng. Mô hình OSI còn có một số thuận lợi sau:
- Chia nhỏ các hoạt động phức tạp của mạng thành các phần công việc đơn giản.
- Cho phép các nhà thiết kế có khả năng phát triển trên từng modun chức năng.
- Cung cấp các khả năng định nghĩa các chuẩn giao tiếp có tính tương thích cao ”plug and play” và tích hợp nhiều nhà cung cấp sản phẩm. 2.1.2. Cấu trúc mô hình OSI Mô hình cấu trúc OSI gồm 7 lớp (level), mỗi lớp thực hiện các chức năng riêng cho hoạt động kết nối mạng.
Mô tả 7 lớp OSI. 4 lớp đầu định nghĩa cách thức cho đầu cuối thiết lập kết nối với nhau để trao đổi dữ liệu. 3 lớp trên dùng để phát triển các ứng dụng để đầu cuối kết nối với nhau và người dùng. Các lớp trên
- Application layer : đây là lớp cao nhất trong mô hình. Nó là nơi mà người sử dụng hoặc kết nối các chương trình ứng dụng với các thủ tục cho phép truy nhập vào mạng.
- Presentation layer : Lớp presentation cung cấp các mã và chức năng để chuyển đổi mà được cung cấp bởi lớp ứng dụng. Các chức năng đó đảm bảo rằng dữ liệu từ lớp ứng dụng trong một hệ thống có thể được đọc bởi lớp ứng dụng của một hệ thống khác. VD : dùng để mã hóa dữ liệu từ lớp ứng dụng: như mã hóa ảnh jpeg, gif. Mã đó cho phép ta có thể hiện lên trang web.
- Session layer : được sử dụng để thiết lập, duy trì và kết thúc phiên làm việc giữa các lớp presentation. Việc trao đổi thông tin ở lớp này bao gồm yêu cầu dịch vụvà đáp ứng yêu cầu của các ứng dụng trên thiết bị khác. Các lớp dưới 4 lớp dưới của mô hình OSI sử dụng để định nghĩa làm thế nào để dữ liệu được truyền đi trong các dây nối vật lý, các thiết bị mạng và đi đến trạm đầu cuối, cuối cùng là đến các lớp ứng dụng. Ở đây ta chỉ quan tâm đến 4 lớp cuối. Và sẽ xem xét từng lớp một cách chi tiết giao thiếp giữa các lớp trong mô hình OSI: Sử dụng phương pháp protocal stack để kết nối giữa hai thiết bị trong mạng. Protocalstack là một tập hợp các quy định dùng để định nghĩa làm thế nào để dữ liệu truyền qua mạng.
2.2 Họ giao thức TCP/IP
Application: Xác nhận quyền, nén dữ liệu và các dịch vụ cho người dùng. Transport: Xử lý dữ liệu giữa các hệ thống và cung cấp việc truy cập mạng cho các ứng dụng. Network: Tìm đường cho các packet. Link: Mức OS hoặc các thiết bị giao tiếp mạng trên một máy tính.
Một số điểm khác nhau của TCP/IP và mô hình OSI
- Lớp ứng dụng trong TCP/IP xử lý chức năng của lớp 5,6,7 trong mô hình OSI
- Lớp transport trong TCP/IP cung cấp cớ chế UDP truyền không tin cậy, transport trong OSI luôn đảm bảo truyền tin cậy
- TCP/IP là một tập của các protocols (một bộ giao thức)
- TCP/IP xây dựng trước OSI
Quy trình đóng gói dữ liệu trong mô hình TCP/IP như sau:
2.3 So sánh giữa hai giao thức TCP và UDP
TCP (Transmission Control Protocol - "Giao thức điều khiển truyền vận") Là một trong các giao thức cốt lõi của bộ giao thức TCP/IP. Sử dụng TCP, các ứng dụng trên các máy chủ được nối mạng có thể tạo các "kết nối" với nhau, mà qua đó chúng có thể trao đổi dữ liệu hoặc các gói tin. Giao thức này đảm bảo chuyển giao dữ liệu tới nơi nhận một cách đáng tin cậy và đúng thứ tự. TCP còn phân biệt giữa dữ liệu của nhiều ứng dụng (chẳng hạn, dịch vụ Web và dịch vụ thư điện tử) đồng thời chạy trên cùng một máy chủ. UDP (User Datagram Protocol) Là một trong những giao thức cốt lõi của giao thức TCP/IP. Dùng UDP, chương trình trên mạng máy tính có thể gởi những dữ liệu ngắn được gọi là datagram tới máy khác. UDP không cung cấp sự tin cậy và thứ tự truyền nhận mà TCP làm, các gói dữ liệu có thể đến không đúng thứ tự hoặc bị mất mà không có thông báo. Tuy nhiên UDP nhanh và hiệu quả hơn đối với các mục tiêu như kích thước nhỏ và yêu cầu khắt khe về thời gian. Do bản chất không trạng thái của nó nên nó hữu dụng đối với việc trả lời các truy vấn nhỏ với số lượng lớn người yêu cầu.
3. LẬP TRÌNH MẠNG .NET FRAMEWORK
3.1. Socket không hướng kết nối (UDP Socket)
Socket là một giao diện lập trình ứng dụng (API) mạng. Thông qua giao diện này chúng ta có thể lập trình điều khiển việc truyền thông giữa hai máy sử dụng các giao thức mức thấp là TCP, UDP…
- Các loại socket
- Socket hướng kết nối (TCP ).
- Socket không hướng kết nối (UDP).
- Raw Socket.
- Đặc điểm của Socket không hướng kết nối (UDP)
- Hai tiến trình liên lạc với nhau không kết nối trực tiếp.
- Thông điệp gửi đi phải kèm theo địa chỉ của người nhận.
- Thông điệp có thể gửi nhiều lần.
- Người gửi không chắc chắn thông điệp tới tay người nhận.
- Thông điệp gửi sau có thể đến đích trước thông điệp gửi trước đó.
- Số hiệu của cổng Socket
- Để có thể thực hiện các cuộc giao tiếp, một trong hai quá trình phải công bố số hiệu cổng của socket mà mình sử dụng.
- Mỗi cổng giao tiếp thể hiện một địa chỉ xác định trong hệ thống. Khi quá trình được gán một số hiệu cổng, nó có thể nhận dữ liệu gửi đến cổng này từ các quá trình khác.
- Quá trình còn lại cũng yêu cầu tạo ra một socket.
- Rất nhiều ứng dụng trên Internet sử dụng UDP. Dựa trên các ưu và nhược điểm của UDP chúng ta có thể kết luận UDP có ích khi:
Sử dụng cho các phương thức truyền broadcasting và multicasting khi chúng ta muốn truyền tin với nhiều host.
- Kích thước datagram nhỏ
- Không cần thiết lập liên kết
- Không cần truyền lại các gói tin
- Ứng dụng không gửi các dữ liệu quan trọng
- Băng thông của mạng đóng vai trò quan trọng Lớp UDPClient Giao thức UDP (User Datagram Protocol hat 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 sang 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. Trong .NET, lớp UDPClient(nằm trong System.Net.Sockets) đóng gói các chức năng của giao thức UDP.
Method | |
---|---|
UdpClient() | Tạo mới đố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(IPEngPoint) | Tạo một UdpClient và gắn (bind) một IPEndPoint (gán địa chỉ IP và cổng) cho nó. |
UdpClient(Int32, AddressFamily) | Tạo một UdpClient và gán số hiệu cổng AddressFamily |
UdpClient(String, Int32) | Tạo một UdpClient và thiết lập một trạm từ xa mặc định. |
Method | |
---|---|
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 | 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 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. |
4. XÂY DỰNG ỨNG DỤNG CLIENT/SERVER NHẬN HÌNH ẢNH TỪ CAMERA GỬI VỀ MÁY TÍNH
Method gửi ảnh từ Camera lên Server.
// Gửi ảnh từ camera lên Server private void GuiDl() { while (true) { try { UdpClient send = new UdpClient(); IPEndPoint iepRemote = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 6969); byte[] data1=new byte[1024]; string camera = "ca1"; byte[] data = new byte[1024]; data = Encoding.ASCII.GetBytes(camera); if (anh != null) { try { Image tam = ResizeByWidth(anh, 100); data1 = imageToByteArray(tam); byte[] data2 = Combine(data, data1); client.send(data2); data2 = null; send.Close(); }catch (Exception e) {} } }catch (Exception e) {} Thread.Sleep(sleep); } }
Method cắt ảnh.
public Image ResizeByWidth(Image img, int awidth) { // lấy chiều rộng và chiều cao ban đầu của ảnh int originalW = img.Width; int originalH = img.Height; // lấy chiều rộng và chiều cao mới tương ứng với chiều rộng truyền vào của ảnh (nó sẽ giúp ảnh của chúng ta sau khi resize vần giứ được độ cân đối của tấm ảnh int resizedW = awidth; int resizedH = (originalH * resizedW) / originalW; // tạo một Bitmap có kích thước tương ứng với chiều rộng và chiều cao mới Bitmap bmp = new Bitmap(resizedW, resizedH); // tạo mới một đối tượng từ Bitmap Graphics graphic = Graphics.FromImage((Image)bmp); graphic.InterpolationMode = InterpolationMode.High; // vẽ lại ảnh với kích thước mới graphic.DrawImage(img, 0, 0, resizedW, resizedH); // gải phóng resource cho đối tượng graphic graphic.Dispose(); // trả về anh sau khi đã resize return (Image)bmp; }
Method chuyển ảnh thành byte
//Chuyển ảnh thành byte private byte[] imageToByteArray(Image imageIn) { MemoryStream ms = new MemoryStream(); imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Png); return ms.ToArray(); }
Server nhận và gửi dữ liệu.
String loi = "loi"; String kiemtra = ""; String[] chuoi = null; Program p = new Program(); //Nhận dữ liệu từ Client gửi lên UdpClient receiver = new UdpClient(6969); IPEndPoint iep = new IPEndPoint(IPAddress.Any, 0); byte[] data = new byte[1024]; data = receiver.Receive(ref iep); kiemtra = Encoding.ASCII.GetString(data); String moi = kiemtra; kiemtra = kiemtra.Substring(0, 3); Console.WriteLine("nhan duoc du lieu tu Client {0}", kiemtra ); if (kiemtra.Equals("log")) { //XỬ lý chuổi khi đăng nhập chuoi = p.Cahtchuoi(data); //Kiểm tra CSDL data = p.Kiemtracsdl(chuoi[0], chuoi[1]); } //Gửi dữ liệu về Client iep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9696); receiver.Send(data, data.Length, iep); kiemtra = null; while (true) { try { //Nhận dữ liệu từ ClientCamera gửi lên data = receiver.Receive(ref iep); kiemtra = Encoding.ASCII.GetString(data); kiemtra = kiemtra.Substring(0, 3); Console.WriteLine("nhan duoc du lieu tu Client {0}", data.Length); if (kiemtra.Equals("log")) { //XỬ lý chuổi khi đăng nhập chuoi = p.Cahtchuoi(data); //Kiểm tra CSDL data = p.Kiemtracsdl(chuoi[0], chuoi[1]); } //Gửi dữ liệu về ClientPhone iep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9696); receiver.Send(data, data.Length, iep); kiemtra = null; } catch (Exception e) { } }
Method nhận dữ liệu từ Server gửi đến
//Nhận dữ liệu từ Server gửi đến private void NhanDl() { while (true) { try { byte[] tencam = null; byte[] data = clPhone.Receive(Port); //Chuyển byte thành chuỗi String kiemtra = Encoding.ASCII.GetString(data); int m = data.Length; //Lấy tên Camera tencam = data.Take(3).ToArray(); //Lấy dữ liệu ảnh data = data.Skip(3).Take(m - 3).ToArray(); String ten = Encoding.ASCII.GetString(tencam); string kiemtra1 = kiemtra.Substring(0, 3); String chuoi = kiemtra.Substring(3); byte[] data1 = Encoding.ASCII.GetBytes(chuoi); //Kiểm tra dữ liệu nhận về if (!(kiemtra1.Equals("tat"))&&ten.Equals("ca1")) { //Hiển thị ảnh lên PictureBox pictureBox1.Image = byteArrayToImage(data); } } catch (Exception e) { } } }
Method chuyển byte thành ảnh
private Image byteArrayToImage(byte[] byteArrayIn) { Image returnImage = null; try { MemoryStream ms = new MemoryStream(byteArrayIn); returnImage = Image.FromStream(ms); } catch (Exception e) { } return returnImage; }