Giao thức cho ứng dụng Client/Server

Một phần của tài liệu Sử Dụng Kỹ Thuật Lập Trình Socket Xây Dựng Chương Trình Truyền File Qua Mạng Lan (Trang 44 - 61)

- Giao thức ở đây là bộ các khuôn dạng bản tin, tập trạng thái và các quy tắc, quy ước trong truyền thông giữa client và server.

- Khi tạo ra một ứng dụng client/server, việc đầu tiên là phải thiết kế giao thức. May mắn cho chúng ta là các giao thức phổ biến như FTP, HTTP, SMTP, RPC... đều đã đươc IETF (nằm trong Internet Architecture Board-IAB) chuẩn hóa thành các giao thức chuẩn. Các chuẩn này được được đưa trong khuyến nghị của IAB gọi là RFC (Request for Comment). Mỗi một chuẩn hoặc một giao thức cho Internet đều được đánh số trong RFC.

- Khi lập trình database theo mô hình client/server, giao thức trao đổi các câu truy vấn và tập các bản ghi đã được quy định và hỗ trợ bởi hệ quản trị Database DBMS và các thư viện lập trình. Do đó, ta cũng không phải quan tâm thiết kế giao thức truyền thông trong ứng dụng database. Khi lập trình sẽ có s n các giao diện giúp ta thực thi việc tương tác giữa Client và Database server. Trong môi trường 3 lớp, thì lớp Middleware ở giữa cũng sẽ cung cấp giao diện để thực thi việc gọi hàm từ xa (Remote Procedure Call-RPC). Đây là một kĩ thuật cho phép các ứng dụng client server tương tác với nhau bằng phương pháp gọi hàm thông thường. Nó cung cấp giao diện gọi hàm mà che đi công tác truyền thông client server và việc truyền thông là trong suốt đối với người lập trình. Kĩ thuật này sẽ được trình bày trong phần sau.

- Nói chung là ta nên theo các giao thức chuẩn có s n cho mỗi ứng dụng phổ biến. Tuy nhiên, khi xây dựng một ứng dụng riêng chưa có giao thức chuẩn thì ta phải thiết kế giao thức.

P â :Có thể chia giao thức thành 2 dạng cơ bản : - Giao thức đồng bộ (Synchronous Protocol)

o Trong dạng giao thức này, quá trình truyền thông giữa client và server diễn ra theo hai chiều nhưng không đồng thời mà được thực hiện lần lượt. Mỗi bên sau khi truyền dữ liệu hoặc thông báo cho bên kia sẽ ngừng lại để chờ bên kia gửi sang

o Ví dụ về các giao thức kiểu này là : HTTP, POP, SMTP... - Giao thức không đồng bộ (Asynchronous Protocol)

o Đối với giao thức dạng không đồng bộ, client và server có thể đồng thời gửi thông tin cho nhau mà không cần phải chờ đợi phản hồi của bên kia

o Các giao thức này thường là các giao thức stateless như TELNET, RLOGIN...

- Ngoài ra có thể có dạng giao thức hybrid là sự kết hợp của hai dạng giao thức đồng bộ và không đồng bộ

Các yêu cầu ố ớ

Việc thiết kế được một giao thức tốt là rất khó khăn và phải đáp ứng các yêu cầu cơ bản sau:

- Rõ ràng (well-defined)

o Trong mỗi dạng bản tin được truyền đi, mọi trường dữ liệu phải được định nghĩa trong giao thức - rõ ràng về kích thước, ý nghĩa, các trường hợp liên quan đến từng bit.

o Giao thức chính là ngôn ngữ, do đó đòi hỏi phải chính xác, không có sự nhập nhằng

o Sử dụng các phương pháp diễn tả mang tính hình thức (common formal decscription) như dạng BNF (trong automata)

o Nếu sử dụng các ngôn ngữ mô tả thì dạng ngôn ngữ đó cũng phải được trình bày trong tài liệu giao thức (để người đọc có thể hiểu được)

o Nên sử dụng các ví dụ minh họa cho giao thức

- Đầy đủ (bao hết mọi khả năng có thể), là các vấn đề sau:

o Dữ liệu hỏng, không hợp lệ (khuôn dạng, kích thước, tránh tràn bộ đệm) Các phiên bản cũ (tương thích). Ví dụ, một client phiên bản proto là 1.0 kết nối với server phiên bản 1.2

o Các yêu cầu không hợp lệ. Lệnh sai hoặc tham số sai hoặc trình tự yêu cầu không đúng quy tắc, hoặc lệnh không được phép...

o Các điều kiện giới hạn. Kiểm tra một số điều kiện nào đó trước khi tiến hành bước tiếp theo. Ví dụ, kiểm tra tính xác thực, kiểm tra điều kiện cho phép...

o Có thể phân tích cú pháp trong các bản tin.

- Một số vấn đề khác khi thiết kế và triển khai giao thức

o Khả năng mở rộng và tương thích giữa các version

o Thứ tự byte

o Tính hiệu quả : Đồng bộ và không đồng bộ Thông tin điều khiển, header Thời gian trễ round trip

o Trạng thái :Ai đọc, ai ghi (ai truyền, ai nhận)

o Timeout : Đây là vấn đề không thể thiếu đối với ứng dụng mạng do tính biến động và không biết trước của trạng thái mạng.

CHƢƠNG III

PHÂN TÍCH THIẾT KẾ CHƢƠNG TRÌNH

3.1.MỤC ĐÍCH CỦA ĐỀ TÀI

Xây dựng chương trình trao đổi file giữa các máy trong mạng Lan với nhau thông qua mô hình Cient/Server. Chức năng cơ bản của chương trình là Server gửi file cho Client.

3.2.GIỚI THIỆU VỀ CHƢƠNG TRÌNH

- Dựa trên yêu cầu muốn trao đổi file giữa các máy trong mạng Lan với nhau thông qua mô hình Cient/Server. Dựa trên kiến thức đã học trong môn Kỹ thuật Phần mềm ứng dụng nhóm đã xây dựng chương trình Truyền File Mạng Lan được viết trên ngôn ngữ C#.

- Chương trình có giao diện đơn giản, trực quan giúp người sử dụng có thể dễ dàng thao tác với các điều khiển.

Quy trình hoạt động của chương trình :

Hình III - 1. Quá trình kết nối

socket(): Client yêu cầu tạo một socket để có thể sử dụng các dịch vụ của tầng vận chuyển.

connect(): Client gởi yêu cầu nối kết đến Server có địa chỉ IP và port xác định.

accept(): Server chấp nhận nối kết của Client, kênh giao tiếp ảo được hình thành,Client và Server có thể trao đổi thông tin với nhau.

 Sau khi Server chấp nhận kết nối từ Client thì Server cũng sẽ truyền file cho Client. Client tiếp nhận và lưu file.

3.3.GIỚI THIỆU THÀNH VIÊN VÀ PHÂN CÔNG NHIỆM VỤ: 3.3.1. Giới thiệu thành viên:

Nhóm gồm 4 thành viên bao gồm:

1) Lưu Đình Hoàng ĐT4-K52 SHSV 20071232 2) Hoàng Trung Long ĐT6-K52 SHSV 20071764 3) Phạm Thị Ngọc ĐT8-K52 SHSV 20076216 4) Đỗ Nguyễn Ngọc Nguyên ĐT3-K52 SHSV 20072127

3.3.2. Phân công nhiệm vụ các thành viên:

3.3.2.1. K :

Tuần 7:

+ Tìm hiểu về mạng máy tính, giao thức FTP, Socket. + Lựa chọn ngôn ngữ lập trình, cụ thể là C#

Tuần 8:

+ Cài đặt Visual Studio và ôn lại các kỹ năng lập trình C#. +Tập code ứng dụng vào bài tập.

Tuần 9,10,11,12,13:

+ Thiết kế chương trình theo yêu cầu cho s n  Tuần 14: Viết và nộp báo cáo.

3.3.2.1. P â :

Tuần 7:

+ Cả nhóm họp và thống nhất chọn ngôn ngữ lập trình C# + Hoàng, Ngọc : Tìm hiểu giao thức trao đổi file FTP + Long, Nguyên: Tìm hiểu Socket

+ Cả nhóm: Tìm hiểu tổng quan mạng máy tính  Tuần 8:

+ Cả nhóm cùng cài đặt Visual C#, ôn lại kỹ năng lập trình. Tập code cho thuật toán.

Tuần 9,10,11,12,13:

+ Ngọc: Thiết kế giao diện

+ Hoàng: Thiết kế lập trình giao diện, lập trình giao thức FTP

+ Long, Nguyên: lập trình Socket.  Tuần 14: Cả nhóm cùng hoàn thiện báo cáo.

3.4.GIAO DIỆN VÀ SỬ DỤNG CHƢƠNG TRÌNH: 3.4.1. Giao diện:

3.4.1.1. Se e

Hình III - 2. Giao diện chƣơng trình Server

e ợ sử ụ ở Se e using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Net.Sockets; using System.Net; using System.Text; using System.Windows.Forms; using System.Threading;

namespace RunServer {

publicpartialclassServer : Form

{

publicdelegatevoidUpdateListBoxCallBack(string s); publicdelegatevoidUpdateLabelCallBack(string s); publicdelegatevoidUpdatepgdstatus(int s,int p); privateNetworkStream nwkStream = null;

privateSocket socketForClient = null; privateTcpListener tcpListener = null; privateStream stmReader = null; privateStream stmWriter = null; privateThread t = null;

public Server() {

InitializeComponent();

IPHostEntry ips = Dns.GetHostByName(Dns.GetHostName()); ipnhan.Text = ips.AddressList[0].ToString();

portnhan.Text = "Nhập số hiệu port";

txtFileName.Text = " Kích vào Browse để chọn file"; label5.Text = null;

}

privatevoid Browse(object sender, EventArgs e) {

txtFileName.Clear();

OpenFileDialog fileDialog = new OpenFileDialog(); fileDialog.Title = "Chon File Gui Cho Client";

fileDialog.Filter = "Text Files (*.txt)|*.txt|Word Documents" +

"(*.doc)|*.doc|All Files (*.*)|*.*"; fileDialog.Multiselect = true; fileDialog.ShowReadOnly = true;

if (fileDialog.ShowDialog(this) == DialogResult.OK) {

txtFileName.Text = fileDialog.FileName; lblMessage.Text = null;

} }

privatevoid btnStart_Click(object sender, EventArgs e) {

t = new Thread(new ThreadStart(startSever)); txtFileName.Clear();

lblMessage.Text = ""; lblProgressbar.Text = ""; pgbStatus.Value = 0; }

privatevoid startSever() { try

{

set1("Listening");

IPEndPoint ip = new IPEndPoint(IPAddress.Parse(ipnhan.Text),

int.Parse(portnhan.Text));

tcpListener = newTcpListener(ip); tcpListener.Start();

socketForClient = tcpListener.AcceptSocket(); if (socketForClient.Connected)

{

NetworkStream ns = newNetworkStream(socketForClient); StreamReader sr = new StreamReader(ns);

StreamWriter sw = newStreamWriter(ns); string filename = txtFileName.Text;

nwkStream = newNetworkStream(socketForClient); stmReader = File.OpenRead(txtFileName.Text); stmWriter = nwkStream;

FileInfo flInfo = newFileInfo(txtFileName.Text); int size = Convert.ToInt32(flInfo.Length);

byte[] buff = newbyte[2048]; int len = 0;

int progress = 0; set1("Starting");

sw.WriteLine(filename); sw.Flush();

while ((len = stmReader.Read(buff, 0, 2048)) != 0) {

progress += len; set3(size,progress);

set(progress.ToString()+" Byte of "+size +" Byte"); stmWriter.Write(buff, 0, len);

stmWriter.Flush(); }

set1("File has sent succesfully!"); }

}

catch (Exception ex) { MessageBox.Show(ex.ToString()); } finally { if (socketForClient != null) { socketForClient.Close(); nwkStream.Close();

stmWriter.Close(); stmReader.Close(); tcpListener.Stop(); } } }

void set1(string s) {

if (InvokeRequired) {

object[] pList = { s };

lblMessage.BeginInvoke(newUpdateListBoxCallBack(OnUpdateLabel), pList); } else { OnUpdateLabel(s); } }

privatevoid OnUpdateLabel(String s) {

lblMessage.Text = s; }

void set(string s) {

if (InvokeRequired) {

object[] pList = { s };

lblProgressbar.BeginInvoke(new

UpdateListBoxCallBack(OnUpdateLabel1), pList); } else { OnUpdateLabel1(s); } }

privatevoid OnUpdateLabel1(String s) {

lblProgressbar.Text = s; }

void set3(int s,int p) {

if (InvokeRequired) {

object[] pList = { s,p };

pgbStatus.BeginInvoke(newUpdatepgdstatus(OnUpdatepgdstatus), pList); }

{

OnUpdatepgdstatus(s,p); }

}

privatevoid OnUpdatepgdstatus(int s,int p) {

pgbStatus.Maximum = s; pgbStatus.Value = p; }

privatevoid Start(object sender, EventArgs e) {

t.Start(); }

privatevoid sukien2(object sender, EventArgs e) {

portnhan.Clear(); }

privatevoid clearPort(object sender, EventArgs e) {

portnhan.Clear(); }

privatevoid ClearFile(object sender, EventArgs e) {

txtFileName.Clear(); }

privatevoid thongtin(object sender, EventArgs e) {

MessageBox.Show("Chương trình được xây dựng bởi Hoàng - Long - Ngọc - Nguyên - SET*HUST", "Thông Tin Chương Trình", MessageBoxButtons.OKCancel,

MessageBoxIcon.Information); }

privatevoid disconnect(object sender, EventArgs e) {

label5.Text = "Kết nối đã bị ngắt"; socketForClient.Close();

tcpListener.Stop(); }

privatevoid exit(object sender, EventArgs e) {

Close(); }

{ txtFileName.Clear(); } } } 3.4.1.2. e

Hình III - 3. Giao diện chƣơng trình Client

e ợ sử ụ ở e using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Net.Sockets; using System.Net; using System.Text; using System.Windows.Forms; using System.Threading; namespace GuiClient {

publicpartialclass Client : Form {

publicdelegatevoid UpdateLabelCallBack(string s); private Stream stmReader = null;

private NetworkStream nwkStream = null; private Stream stmWriter = null;

private TcpClient tcpClient = null; private Thread t = null;

SaveFileDialog saveFileDialog = new SaveFileDialog(); public Client()

{

InitializeComponent(); }

privatevoid btnSave_Click(object sender, EventArgs e) {

t = new Thread(new ThreadStart(SaveFile)); t.Start();

}

publicvoid SaveFile() { txtFileName.Text = saveFileDialog1.FileName; set(null); try { nwkStream = tcpClient.GetStream(); stmReader = nwkStream; stmWriter = File.OpenWrite(txtFileName.Text); byte[] buff = new byte[1024];

int len = 0; set("Receiving");

while ((len = stmReader.Read(buff, 0, 1024)) > 0) {

stmWriter.Write(buff, 0, len); stmWriter.Flush();

}

set("File has received succesfully!"); }

catch (Exception ex) { MessageBox.Show(ex.ToString()); } finally { nwkStream.Close(); stmWriter.Close();

stmReader.Close(); }

}

publicvoid Start(object sender, EventArgs e) {

txtFileName.Clear();

IPEndPoint ipe = new IPEndPoint(IPAddress.Parse(ipserver.Text),

int.Parse(port.Text));

tcpClient = new TcpClient(); tcpClient.Connect(ipe);

StreamReader sr = new StreamReader(tcpClient.GetStream()); StreamWriter sw = new StreamWriter(tcpClient.GetStream()); string duongdan = sr.ReadLine();

textBox1.Text = "Server gui file : " + duongdan; saveFileDialog1.FileName = duongdan;

saveFileDialog1.Title = "Luu File Tu Server";

saveFileDialog1.Filter = "Text Files (*.txt)|*.txt|Word Documents" +

"(*.doc)|*.doc|All Files (*.*)|*.*";

saveFileDialog1.ShowHelp = true;

if (saveFileDialog1.ShowDialog(this) == DialogResult.OK) {

txtFileName.Text = saveFileDialog1.FileName; set(null);

} }

void set(string s) {

if (InvokeRequired) {

object[] pList = { s };

lblMessage.BeginInvoke(new UpdateListBoxCallBack(OnUpdateLabel), pList); } else { OnUpdateLabel(s); } }

privatevoid OnUpdateLabel(String s) {

lblMessage.Text = s; }

privatevoid clearip(object sender, EventArgs e) {

ipserver.Clear(); }

privatevoid clearport(object sender, EventArgs e) {

port.Clear(); }

privatevoid clearfilename(object sender, EventArgs e) {

txtFileName.Clear(); }

privatevoid exit(object sender, EventArgs e) {

Close(); }

privatevoid disconectToolStripMenuItem_Click(object sender, EventArgs e) {

nwkStream.Close(); stmWriter.Close(); stmReader.Close(); }

privatevoid txtFileName_TextChanged(object sender, EventArgs e) {

}

privatevoid textBox1_TextChanged(object sender, EventArgs e) {

}

privatevoid ipserver_TextChanged(object sender, EventArgs e) {

}

privatevoid port_TextChanged(object sender, EventArgs e) {

}

privatevoid txtFileName_TextChanged_1(object sender, EventArgs e) {

} }

3.4.2. Sử dụng chƣơng trình:

Se e Chương trình tại Server sẽ được kích hoạt trước.

- IP : Chương trình sẽ lấy địa chỉ ip của Card mạng tại Server và gán vào phần địa chỉ IP

- Port : Tại đây Server sẽ sử dụng 1 port để truyền file, số hiệu port này sẽ được gán từ người sử dụng tại Server.

- Sau khi đã điền thông tin về địa chỉ và số hiệu port của Server thì kích vào điều khiển Connect để kích hoạt.

- Tiếp theo chọn file cần truyền cho Client bằng cách kích vào điều khiển Browse

và chọn file đến file cần truyền. Tại ô File sẽ xuất hiện đường dẫn của file đã chọn.

- Kích chọn điều khiển Start để lắng nghe, và khi một máy Client kết nối đến thì File sẽ được truyền đi. Trạng thái lắng nghe và báo hiệu khi máy Client đã nhận được File sẽ được biểu diễn ở Status.

Client: Sau khi chương trình Server đã được kích hoạt thì khi đó tại Client cần phải thực hiện các bước sau để nhận File.

- IP : Tại địa chỉ ip người sử dụng Client sẽ điền địa chỉ của máy Server cần kết nối đến.

- Port : Số hiệu port này sẽ dùng số hiệu port mà bên Server đã sử dụng để truyền.

- Sau khi bên Server đã hoàn thành xong các bước để bắt đầu lắng nghe kết nối từ Client thì tại Client sẽ kết nối bằng điều khiển Start.

- Khi máy Client đã kết nối thì File bên Server đã được truyền đến và tên File sẽ được hiển thị tại Thông Báo Server gửi file.

- Tiếp theo Client muốn nhận được File thì kích chọn điều khiển Save để lưu File vào máy.

KẾT LUẬN

Qua đồ án nhóm chúng em có củng cố lại kiến thức đã đƣợc học. Và dƣới sự hƣớng dẫn nhiệt tình của Thầy Vũ Song Tùng đã giúp đỡ nhóm chúng em hoàn thiện chƣơng trình “Truyền File Qua Mạng Lan” một cách hoàn chỉnh.

Chƣơng trình của nhóm còn nhiều hạn chế mong Thầy Cô và các bạn có những nhận xét đóng góp ý kiến để nhóm có thể hoàn thiện và phát triển chƣơng hơn nhằm làm cho chƣơng trình có thể đƣợc ứng dụng dễ dàng nhƣng mang lại hiệu quả khi truyền file

TÀI LIỆU THAM KHẢO

[1]. Giáo Trình Lập Trình Mạng [2]. Các trang Web o http://google.com.vn o http://www.wikipedia o http://www.tailieu.vn o http://www.codeproject o http://kilobook.com.vn

Một phần của tài liệu Sử Dụng Kỹ Thuật Lập Trình Socket Xây Dựng Chương Trình Truyền File Qua Mạng Lan (Trang 44 - 61)

Tải bản đầy đủ (PDF)

(61 trang)