41
Đại Học Bách Khoa Hà Nội Viện Điện tử viễn thông ---------------o0o--------------- BÁO CÁO BÀI TẬP LỚN Kỹ thuật mạng nâng cao Đề tài : Lập trình UDP socket giao tiếp Client Server Giảng viên hướng dẫn: Sinh viên thực hiện : Nguyễn Thế Hưng ĐT8 - K52 20071475 Phạm Thu Hường Nguyễn Ngọc Kiều

Bao Cao Mang Nang Cao

  • Upload
    telbook

  • View
    127

  • Download
    3

Embed Size (px)

Citation preview

Page 1: Bao Cao Mang Nang Cao

Đại Học Bách Khoa Hà NộiViện Điện tử viễn thông

---------------o0o---------------

BÁO CÁO BÀI TẬP LỚN

Kỹ thuật mạng nâng cao

Đề tài : Lập trình UDP socket giao tiếp Client Server

Giảng viên hướng dẫn:

Sinh viên thực hiện :Nguyễn Thế Hưng ĐT8 - K52 20071475

Phạm Thu Hường

Nguyễn Ngọc Kiều

Hà Nội, tháng 10 năm 2011

Page 2: Bao Cao Mang Nang Cao

Mục lục

ContentsMục lục........................................................................................................................................................2

Yêu cầu đề tài:............................................................................................................................................3

I. Các kiến thức cơ bản về máy tính......................................................................................................4

1. Họ giao thức TCP/IP........................................................................................................................4

2. Giao thức UDP.................................................................................................................................5

a. Khái quát........................................................................................................................................5

b. Cổng................................................................................................................................................5

c. Cấu trúc gói.....................................................................................................................................6

II. UDP socket..........................................................................................................................................7

a. Socket.............................................................................................................................................7

b. Giới thiệu về NameSpace System.Net và System.Net.Sockets.........................................................8

III. Lập trình..........................................................................................................................................9

1. Giao diện........................................................................................................................................9

a. Server..........................................................................................................................................9

b. Client........................................................................................................................................10

2. Chương trình...............................................................................................................................10

a. Server........................................................................................................................................10

b. Client........................................................................................................................................24

c. Class Data định nghĩa dữ liệu trao đổi Client và Server.......................................................28

Page 3: Bao Cao Mang Nang Cao

Yêu cầu đề tài:

Tạo chương trình Client-Server trao đổi thông tin qua UDP socket thực hiện các chức năng sau :- Client sau khi kết nối sẽ gửi tới server thông tin về địa chỉ Mac của client - Server sau khi nhận thông tin sẽ kiểm tra thông tin về client đó đã được ghi vào file hay

chưa, nếu chưa sẽ lưu vào file. Sau đó gửi lại client bản tin xác nhận đã nhận, ghi, đã có thông tin.

- Server lưu giữ thông tin các client hiện đang kết nối vào server.Client muốn ngắt kết nối cần gửi bản tin thông báo cho server

- Khi có client khác kết nối vào server, server gửi cho các client khác thông tin về client mới kết nối vào.Client nhận được bản tin này sẽ hiển thị thông tin mac của client mới kết nối vào server

Page 4: Bao Cao Mang Nang Cao

I. Các kiến thức cơ bản về máy tính

1. Họ giao thức TCP/IP

Hình 1-3: Các tầng của giao thức TCP/IP so với cấc tầng của mô hình OSIApplication: 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 va 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

Page 5: Bao Cao Mang Nang Cao

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

2. Giao thức UDPa. Khái quát

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.

Những ứng dụng phổ biến sử dụng UDP như DNS (Domain Name System), ứng dụng streaming media, Voice over IP, Trivial File Transfer Protocol (TFTP), và game trực tuyến

b. Cổng

UDP dùng cổng để cho phép các giao tiếp giữa các ứng dụng diễn ra.

Cổng dùng 16 bit để đánh địa chỉ, vì vậy số của cổng nằm trong khoản 0 đến 65.535. Cổng 0 được để dành và không nên sử dụng.

Cổng từ 1 đến 1023 được gọi là cổng "well-known" và trên các hệ điều hành tựa Unix, việc gắn kết tới một trong những cổng này đòi hỏi quyền root.

Page 6: Bao Cao Mang Nang Cao

Cổng 1024 đến 49.151 là cổng đã đăng ký.

Cổng từ 49.152 đến 65.535 là các cổng tạm, được dùng chủ yếu bởi client khi liên lạc với server

c. Cấu trúc gói

UDP là giao thức hướng thông điệp nhỏ nhất của tầng giao vận hiện được mô tả trong RFC 768 của IETF.

Trong bộ giao thức TCP/IP, UDP cung cấp một giao diện rất đơn giản giữa tầng mạng bên dưới (thí dụ, IPv4) và tầng phiên làm việc hoặc tầng ứng dụng phía trên.

UDP không đảm bảo cho các tầng phía trên thông điệp đã được gửi đi và người gửi cũng không có trạng thái thông điệp UDP một khi đã được gửi (Vì lý do này đôi khi UDP còn được gọi là Unreliable Datagram Protocol).

UDP chỉ thêm các thông tin multiplexing và giao dịch. Các loại thông tin tin cậy cho việc truyền dữ liệu nếu cần phải được xây dựng ở các tầng cao hơn.

Phần header của UDP chỉ chứa 4 trường dữ liệu, trong đó có 2 trường là tùy chọn (ô nền đỏ trong bảng).

Source portTrường này xác định cổng của người gửi thông tin và có ý nghĩa nếu muốn nhận thông tin phản hồi từ người nhận. Nếu không dùng đến thì đặt nó bằng 0.Destination portTrường xác định cổng nhận thông tin, và trường này là cần thiết.LengthTrường có độ dài 16 bit xác định chiều dài của toàn bộ datagram: phần header và dữ liệu. Chiều dài tối thiểu là 8 byte khi gói tin không có dữ liệu, chỉ có header.2Trường checksum 16 bit dùng cho việc kiểm tra lỗi của phần header và dữ liệu. Phương pháp tính checksum được định nghĩa trong RFC 768.

Do thiếu tính tin cậy, các ứng dụng UDP nói chung phải chấp nhận mất mát, lỗi hoặc trùng dữ liệu. Một số ứng dụng như TFTP có nhu cầu phải thêm những kỹ thuật làm tin cậy cơ bản vào tầng ứng dụng. Hầu hết các ứng dụng UDP không cần những kỹ thuật làm tin cậy này và đôi khi nó bị bỏ đi. Streaming media, game trực tuyến và voice over IP (VoIP) là những thí dụ cho các ứng dụng thường dùng UDP. Nếu một ứng dụng đòi hỏi mức độ cao hơn về tính tin cậy, những giao thức như TCP hoặc mã erasure có thể dùng thay.

Thiếu những cơ chế kiểm soát tắc nghẽn và kiểm soát luồng, các kỹ thuật dựa trên mạng là cần thiết để giảm nguy hiệu ứng cơ tắc nghẽn dây chuyền do không kiểm soát, tỷ lệ tải UDP cao. Nói cách khác, vì người gởi gói UDP không thể phát hiện tắc nghẽn, các thành phần dựa trên mạng

Page 7: Bao Cao Mang Nang Cao

như router dùng hàng đợi gói (packet queueing) hoặc kỹ thuật bỏ gói như là những công cụ để giảm tải của UDP. Giao thức Datagram Congestion Control Protocol (DCCP) được thiết kế như một giải pháp cho vấn đề bằng cách thêm hành vi kiểm soát tắc nghẽn cho thiết bị đầu cuối cho các dòng dữ liệu UDP như streaming media.

Mặc dù tổng lượng lưu thông của UDP trên mạng thường chỉ vài phần trăm, nhưng có nhiều ứng dụng quan trọng dùng UDP, bao gồm DNS, SNMP, DHCP và RIP.

II. UDP socket

a. 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…

Socket là sự trừu tượng hoá ở mức cao, có thể tưởng tượng nó như là thiết bị truyền

thông hai chiều gửi - nhận dữ liệu giữa hai máy tính với nhau.

Các loại Socket

Socket hướng kết nối (TCP Socket)

Socket không hướng kết nối (UDP Socket)

Raw Socket

ðặc điểm của Socket hướng kết nối

Có 1 đường kết nối ảo giữa 2 tiến trình

Một trong 2 tiến trình phải ñợi tiến trình kia yêu cầu kết nối.

Có thể sử dụng ñể liên lạc theo mô hình Client/Server

Trong mô hình Client/Server thì Server lắng nghe và chấp nhận một yêu

cầu kết nối

Mỗi thông ñiệp gửi ñều có xác nhận trở về

Các gói tin chuyển đi tuần tự

đặc điểm của Socket không hướng kết nối 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ổng của 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.

Page 8: Bao Cao Mang Nang Cao

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

b. Giới thiệu về NameSpace System.Net và System.Net.Sockets

Cung cấp một giao diện lập trình đơn giản cho rất nhiều các giao thức

mạng.

Có rất nhiều lớp để lập trình

Ta quan tâm lớp IPAdress, IPEndPoint,

DNS, …

Lớp IPAdress Một số Field cần chú ý:

Any: Cung cấp một ñịa chỉ IP ñể chỉ ra rằng Server phải lắng nghe

trên tất cả các Card mạng

Broadcast: Cung cấp một ñịa chỉ IP

quảng bá

Loopback: Trả về một ñịa chỉ IP lặp

AdressFamily: Trả về họ ñịa chỉ của IP hiện

hành

Lớp IPAddress

Một số phương thức cần chú ý:

Phương thức khởi tạo

IPAddress(Byte[])

IPAddress(Int64)

IsLoopback: Cho biết ñịa chỉ có phải ñịa chỉ lặp

không

Parse: Chuyển IP dạng xâu về IP chuẩn

ToString: Trả ñịa chỉ IP về dạng xâu

TryParse: Kiểm tra IP ở dạng xâu có hợp lệ

không?

Lớp IPEndPoint

Cổng, ví dụ: 192.168.1.1:8080 Lớp DNS Một số thành phần của lớp:

HostName: Cho biết tên của máy ñược phân

giải

GetHostAddress: Trả về tất cả IP của một

trạm GetHostEntry: Giải ñáp tên hoặc ñịa chỉ truyền vào và trả về ñối tượng IPHostEntry

Page 9: Bao Cao Mang Nang Cao

GetHostName: Lấy về tên của máy tính cục bộ

NameSpace System.Net.Sockets

Một số lớp hay dùng: TcpClient, UdpClient, TcpListener, Socket,

NetworkStream, …

để tạo ra Socket

Socket(AddressFamily af, SocketType st, ProtocolType pt)III. Lập trình1. Giao diện

a. Server Chưa có client kết nối

Có Client kết nối

Page 10: Bao Cao Mang Nang Cao

b. Client Login

Form chính

2. Chương trìnha. Server

using System;using System.Collections;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;

Page 11: Bao Cao Mang Nang Cao

using System.Text;using System.Windows.Forms;using System.Net;using System.Net.Sockets;using System.Net.NetworkInformation;using System.IO;using System.Text.RegularExpressions;//using System.Data;

namespace Server{ // lenh dung trao doi giua Server va Client enum Command { Login, //Dang nhap toi Server Logout, //Dang xuat khoi Server ACK, //Thong bao da nhan, ghi, da co thong tin MAC ve Client NewClient, //Gui cho Client thong bao dia chi MAC Client moi ket noi Null, //No command Stop //Server will stop after 5s } public partial class Form1 : Form { // // Cau truc ClientInfo giu thong tin va moi Client ket noi vao server struct ClientInfo { public EndPoint endpoint; //Socket cua Client public string strMac; //Dia chi Mac ma Client gui toi ket noi public string strIP; //dia chi IP client }

// Cac Client ket noi vao Server duoc luu vao Mang ArrayList clientList,clientOld;

// Socket chinh ma Server dung de lang nghe Client Socket serverSocket;

// dinh nghia mot byteData byte[] byteData = new byte[1024];

// flag quiting dung cho viec Stop server bool _quiting; // bool _changeView; // port number cho server

Page 12: Bao Cao Mang Nang Cao

int _Port; //flag dung de xac dinh da startserver chua bool fstartSer; // public Form1() { InitializeComponent();

// khoi tao mang clientlist clientList = new ArrayList();

// lay dia chi card mang dang su dung //UdpClient u = new UdpClient("8.8.8.8", 1); //localAddr = ((IPEndPoint)u.Client.LocalEndPoint).Address; //txtIPserver.Text = localAddr.ToString();

// Get host name String strHostName = Dns.GetHostName();

// Find host by name IPHostEntry iphostentry = Dns.GetHostByName(strHostName); // Dns.GetHostByName(strHostName);

// Enumerate IP addresses foreach (IPAddress ipaddress in iphostentry.AddressList) { comboBox1.Items.Add(ipaddress.ToString()); }

// Mac dinh Cong lang nghe la 8888 txtPort.Text = "8888"; _Port = 8888;

// Mac dinh chua chay Server fstartSer = false; button1.Text = "Start Server"; stopToolStripMenuItem.Enabled = false; toolTip1.SetToolTip(this.button1, "Click to Start Server...");

// tooltip toolTip1.SetToolTip(comboBox1, "IP address Server"); toolTip1.SetToolTip(txtPort, "Port number in which Server is listening");

Page 13: Bao Cao Mang Nang Cao

// _changeView = false;

}

private void button1_Click(object sender, EventArgs e) { // if (fstartSer == false) { try { CheckForIllegalCrossThreadCalls = false;

// load cac client da ket noi dua vao clientOld load_old();

// Su dung UDP Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

// gan dia chi IP cua may va lang nghe Port xac dinh boi txtPort _Port = Convert.ToInt32(txtPort.Text); IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, _Port);

// Bind this address to Server serverSocket.Bind(ipEndPoint);

IPEndPoint ipeSender = new IPEndPoint(IPAddress.Any, 0);// chap nhan moi dia chi Client // xac dinh dia chi Client EndPoint epSender = (EndPoint)ipeSender;

// Start receiving data serverSocket.BeginReceiveFrom(byteData, 0, byteData.Length, SocketFlags.None, ref epSender, new AsyncCallback(OnReceive), epSender);

// Doi text Button1 thanh Stop Server button1.Text = "Stop Server"; toolTip1.SetToolTip(this.button1, "Click to Stop Server...");

// tra gia tri flag StartSer ve True fstartSer = true;

Page 14: Bao Cao Mang Nang Cao

// enabel nut Stop trong menu Server stopToolStripMenuItem.Enabled = true; startToolStripMenuItem.Enabled = false; proBar1.Style = ProgressBarStyle.Marquee; changePortNumberToolStripMenuItem.Enabled = false; } catch (Exception ex) { // thong bao loi va Set co FstartServer ve false MessageBox.Show(ex.Message, "ServerUDP", MessageBoxButtons.OK, MessageBoxIcon.Error); fstartSer = false; stopToolStripMenuItem.Enabled = false; startToolStripMenuItem.Enabled = true; proBar1.Style = ProgressBarStyle.Blocks; changePortNumberToolStripMenuItem.Enabled = true; } } else { _quiting = true; try { serverSocket.Close();

// Doi text Button1 thanh Start Server button1.Text = "Start Server"; toolTip1.SetToolTip(this.button1, "Click to Start Server...");

// Set flag StartSer ve false fstartSer = false; stopToolStripMenuItem.Enabled = false; startToolStripMenuItem.Enabled = true; proBar1.Style = ProgressBarStyle.Blocks; changePortNumberToolStripMenuItem.Enabled = true; } catch (Exception ex) { MessageBox.Show(ex.Message); fstartSer = true;

// Doi text Button1 thanh Stop Server button1.Text = "Stop Server"; toolTip1.SetToolTip(this.button1, "Click to Stop Server..."); proBar1.Style = ProgressBarStyle.Marquee; // tra gia tri flag StartSer ve True

Page 15: Bao Cao Mang Nang Cao

fstartSer = true;

// menu Server stopToolStripMenuItem.Enabled = true; startToolStripMenuItem.Enabled = false; changePortNumberToolStripMenuItem.Enabled = false; } }

}

// ham OnReceive duoc goi sau khi ket thuc nhan du lieu tu Client... private void OnReceive(IAsyncResult ar) { bool have = false; try {

// bat loi Stop server o day => tham khao tren mang... IPEndPoint ipeSender = new IPEndPoint(IPAddress.Any, 0); EndPoint epSender = (EndPoint)ipeSender;

try { serverSocket.EndReceiveFrom(ar, ref epSender); } catch (ObjectDisposedException) { if (_quiting) return; throw; }

//convert byteData to msgReceived Data msgReceived = new Data(byteData);

//We will send this object in response the users request Data msgToSend = new Data();

byte[] message; //If the message is to login, logout, or simple text message //then when send to others the type of the message remains the same msgToSend.cmdCommand = msgReceived.cmdCommand; msgToSend.strMac = msgReceived.strMac; msgToSend.strIP = msgReceived.strIP; int nIndex = 0;

Page 16: Bao Cao Mang Nang Cao

switch (msgReceived.cmdCommand) { case Command.Login:

//When a user logs in to the server then we add her to our //list of clients

ClientInfo clientInfo = new ClientInfo(); clientInfo.endpoint = epSender; clientInfo.strMac = msgReceived.strMac; clientInfo.strIP = msgReceived.strIP; foreach (ClientInfo client in clientOld) { if ((client.strMac == msgReceived.strMac)&&(client.strIP == msgReceived.strIP)) { have = true; break; } //++nIndex; } clientList.Add(clientInfo); // ghi file neu chua co client moi if (!have) { StringBuilder sb = new StringBuilder(); sb.AppendLine(msgReceived.strIP + "#" + msgReceived.strMac); using (StreamWriter outfile = new StreamWriter("server.txt", true)) { outfile.Write(sb.ToString()); } } // gui ACK toi client thong bao da nhan dc msgToSend.cmdCommand = Command.ACK; message = msgToSend.ToByte(); serverSocket.BeginSendTo(message, 0, message.Length, SocketFlags.None, epSender, new AsyncCallback(OnSend), epSender); _changeView = true; break; case Command.Logout: //When a user wants to log out of the server then we search for her //in the list of clients and close the corresponding connection

nIndex = 0;

Page 17: Bao Cao Mang Nang Cao

foreach (ClientInfo client in clientList) { if (client.strMac == msgReceived.strMac) { clientList.RemoveAt(nIndex); break; } ++nIndex; } toolStripStatusLabel1.Text = "Client " + msgReceived.strIP + " with Mac add : " + msgReceived.strMac + " logout"; _changeView = true; break; default: break; } // if (msgReceived.cmdCommand == Command.Login) {

msgToSend.cmdCommand = Command.NewClient; message = msgToSend.ToByte(); foreach (ClientInfo clientInfo in clientList) { // //if (clientInfo.endpoint != epSender) { //Gui Mac cho cac Client cu biet co client moi serverSocket.BeginSendTo(message, 0, message.Length, SocketFlags.None, clientInfo.endpoint, new AsyncCallback(OnSend), clientInfo.endpoint); } } //if (!have) toolStripStatusLabel1.Text = "Client " + msgReceived.strIP + " with Mac add : " + msgReceived.strMac + " login"; } ipeSender = new IPEndPoint(IPAddress.Any, 0); epSender = (EndPoint)ipeSender; serverSocket.BeginReceiveFrom(byteData, 0, byteData.Length, SocketFlags.None, ref epSender, new AsyncCallback(OnReceive), epSender); //}

Page 18: Bao Cao Mang Nang Cao

} catch (Exception ex) { MessageBox.Show(ex.Message, "ServerUDP", MessageBoxButtons.OK, MessageBoxIcon.Error); } }

public void OnSend(IAsyncResult ar) { try { serverSocket.EndSend(ar); } catch (Exception ex) { MessageBox.Show(ex.Message, "ServerUDP", MessageBoxButtons.OK, MessageBoxIcon.Error); } }

private void timer1_Tick(object sender, EventArgs e) { this.Text = DateTime.Now.ToString(); }

private void changePortNumberToolStripMenuItem_Click(object sender, EventArgs e) { int p = _Port; if (InputBox("ServerUDP", "Port number to listening", ref p) == DialogResult.OK) { if ((p != 8888) && (p > 1022) && (p < 65536)) { _Port = p; txtPort.Text = _Port.ToString(); } else { if (MessageBox.Show("Port number incorrect !", "ServerUDP", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error) == DialogResult.Retry) { changePortNumberToolStripMenuItem_Click(sender, e); } else

Page 19: Bao Cao Mang Nang Cao

{ MessageBox.Show("Fail to change Port number. Default Port number is 8888", "ServerUDP", MessageBoxButtons.OK, MessageBoxIcon.Warning); _Port = 8888; txtPort.Text = "8888"; } } } else { MessageBox.Show("No change Port number", "ServerUDP", MessageBoxButtons.OK, MessageBoxIcon.Information); } txtPort.Focus(); //Regex rex = new Regex(@"^[a-zA-Z]\w{1,39}$"); // kiem tra dau vao //if (!(rex.Match(server)).Success) //cau lenh tren nghia la khong nam trong tap 0-9

}

public static DialogResult InputBox(string title, string promptText, ref int value) { Form form = new Form(); Label label = new Label(); TextBox textBox = new TextBox(); Button buttonOk = new Button(); Button buttonCancel = new Button();

form.Text = title; label.Text = promptText; textBox.Text = value.ToString(); textBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;

buttonOk.Text = "OK"; buttonCancel.Text = "Cancel"; buttonOk.DialogResult = DialogResult.OK; buttonCancel.DialogResult = DialogResult.Cancel;

label.SetBounds(9, 20, 100, 13); textBox.SetBounds(12, 36, 75, 20); buttonOk.SetBounds(12, 60, 75, 23); buttonCancel.SetBounds(93, 60, 75, 23);

label.AutoSize = true;

Page 20: Bao Cao Mang Nang Cao

textBox.Anchor = textBox.Anchor | AnchorStyles.Right; //buttonOk.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; //buttonCancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;

form.ClientSize = new Size(150, 107); form.Controls.AddRange(new Control[] { label, textBox, buttonOk, buttonCancel }); form.ClientSize = new Size(Math.Max(150, label.Right + 40), form.ClientSize.Height); form.FormBorderStyle = FormBorderStyle.FixedDialog; form.StartPosition = FormStartPosition.CenterScreen; form.ControlBox = false; form.AcceptButton = buttonOk; form.CancelButton = buttonCancel;

DialogResult dialogResult = form.ShowDialog();

//Regex rex = new Regex(@"^[0-9]\w{3,4}$"); try { value = Convert.ToInt32(textBox.Text); } catch (Exception ex) { MessageBox.Show(ex.Message); }

return dialogResult; }

private void startToolStripMenuItem_Click(object sender, EventArgs e) { button1_Click(sender, e); }

private void stopToolStripMenuItem_Click(object sender, EventArgs e) { button1_Click(sender, e); }

private void exitApplicationToolStripMenuItem_Click(object sender, EventArgs e) { if (fstartSer == true) { _quiting = true;

Page 21: Bao Cao Mang Nang Cao

try { serverSocket.Close(); } catch (Exception ex) { MessageBox.Show(ex.Message); } } Application.Exit(); }

private void Form1_FormClosing(object sender, FormClosingEventArgs e) { //Thoát khỏi form thì hiện chuỗi xác nhận với biểu tượng cảnh báo if (MessageBox.Show("Bạn có chắc chắn thoát khỏi chương trình ?", "Thông Báo", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1) == DialogResult.Cancel) { e.Cancel = true; } } private void Form1_Load(object sender, EventArgs e) { clientConnectingToolStripMenuItem.Enabled = false; clientConnectingToolStripMenuItem.Checked = true; proBar1.Step = 1; }

private void clientConnectedToolStripMenuItem_Click(object sender, EventArgs e) { /* try { // Create an instance of StreamReader to read from a file. // The using statement also closes the StreamReader. using (StreamReader sr = new StreamReader("server.txt")) { String line = ""; StreamReader reader = new StreamReader("server.txt");

// Read and display lines from the file until the end of // the file is reached.

Page 22: Bao Cao Mang Nang Cao

do { line = line + reader.ReadLine() + "\r\n"; } while (reader.Peek() != -1); textBox1.Text = line; reader.Close();

} } catch (Exception exx) { MessageBox.Show(exx.Message); } */ try { timer2.Enabled = false; String line = ""; string sIP, sMac; StreamReader reader = new StreamReader("server.txt"); // Read and display lines from the file until the end of // the file is reached. int count = 1; dataGridView1.Rows.Clear(); do { line = reader.ReadLine(); sIP = line.Substring(0, line.IndexOf("#")); sMac = line.Substring(line.IndexOf("#") + 1, line.Length - line.IndexOf("#") - 1); dataGridView1.Rows.Add(count, sIP, sMac); count++; } while (reader.Peek() != -1); reader.Close(); clientConnectedToolStripMenuItem.Enabled = false; clientConnectingToolStripMenuItem.Enabled = true; clientConnectingToolStripMenuItem.Checked = false;

} catch (Exception eh) { MessageBox.Show(eh.Message, "SERVER_UDP", MessageBoxButtons.OK,MessageBoxIcon.Error); clientConnectedToolStripMenuItem.Enabled = true; clientConnectingToolStripMenuItem.Enabled = false;

Page 23: Bao Cao Mang Nang Cao

clientConnectingToolStripMenuItem.Checked = true; }

}

private void timer2_Tick(object sender, EventArgs e) { if (_changeView) { dataGridView1.Rows.Clear();

int count = 1; foreach (ClientInfo tt in clientList) { dataGridView1.Rows.Add(count, tt.strIP, tt.strMac); count++; } _changeView = false; } }

private void clientConnectingToolStripMenuItem_Click(object sender, EventArgs e) { clientConnectedToolStripMenuItem.Enabled = true; clientConnectedToolStripMenuItem.Checked = false; clientConnectingToolStripMenuItem.Enabled = false; _changeView = true; timer2.Enabled = true;

}

private void aboutToolStripMenuItem_Click(object sender, EventArgs e) { MessageBox.Show("Version 1.0\nNguyễn Thế Hưng\nPhạm Thu Hường\nNguyễn Ngọc Kiều","Kỹ thuật mạng nâng cao", MessageBoxButtons.OK); }

private void settingToolStripMenuItem_Click(object sender, EventArgs e) { MessageBox.Show("Nothing", "SERVER_UDP", MessageBoxButtons.OK); }

private void load_old() {

Page 24: Bao Cao Mang Nang Cao

clientOld = new ArrayList(); String line = ""; string sIP, sMac; if (File.Exists("server.txt")) { StreamReader reader = new StreamReader("server.txt"); // Read and display lines from the file until the end of // the file is reached.

do { line = reader.ReadLine(); //if (line[0] == 35)// dau thang sIP = line.Substring(0, line.IndexOf("#")); sMac = line.Substring(line.IndexOf("#") + 1, line.Length - line.IndexOf("#") - 1); ClientInfo temp = new ClientInfo(); temp.strIP = sIP; temp.strMac = sMac; temp.endpoint = null; clientOld.Add(temp); } while (reader.Peek() != -1); reader.Close(); } } } }

b. Clientusing System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using System.Net;using System.Net.Sockets;//using System.Net.NetworkInformation;

namespace Client{ public partial class Login : Form

Page 25: Bao Cao Mang Nang Cao

{ [System.Runtime.InteropServices.DllImport("iphlpapi.dll", ExactSpelling = true)] static extern int SendARP(int DestIP, int SrcIP, byte[] pMacAddr, ref int PhyAddrLen);

public Socket clientSocket; public EndPoint epServer; public string strMac, strIP; private byte[] byteData; private int count; public Login() { InitializeComponent(); }

private void btnCancel_Click(object sender, EventArgs e) { Close(); }

private void Login_Load(object sender, EventArgs e) { CheckForIllegalCrossThreadCalls = false; btnOK.Enabled = false; timer1.Enabled = false; txtIPserver.Text = ""; txtPort.Text = "8888"; }

private void btnOK_Click(object sender, EventArgs e) { //if ((textBox1.Text == "huong") && (textBox2.Text == "bkacad")) { try {

// su dung UDP socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

//IP address cua Server IPAddress IPserver = IPAddress.Parse(txtIPserver.Text);

// lay port server lang nghe

Page 26: Bao Cao Mang Nang Cao

IPEndPoint ipEndPoint = new IPEndPoint(IPserver, Convert.ToInt32(txtPort.Text)); epServer = (EndPoint)ipEndPoint;

// du lieu gui di Data msgToSend = new Data(); msgToSend.cmdCommand = Command.Login;

// lay dia chi card mang va MAC UdpClient u = new UdpClient(txtIPserver.Text, 1); IPAddress localAddr = ((IPEndPoint)u.Client.LocalEndPoint).Address; msgToSend.strIP = localAddr.ToString(); msgToSend.strMac = GetMacAddress(localAddr).ToString();

// bien truyen cho form1 strMac = msgToSend.strMac; strIP = msgToSend.strIP;

//Convert sang Byte byteData = msgToSend.ToByte();

//login to Server clientSocket.BeginSendTo(byteData, 0, byteData.Length, SocketFlags.None, epServer, new AsyncCallback(OnSend), null);

//chuan bi bien luu tru thong tin tra ve byteData = new byte[1024];

//Start listening to the data asynchronously count = 0;

// btnOK.Enabled = false; btnCancel.Enabled = false; timer1.Enabled = true;

// san sang nhan du lieu clientSocket.BeginReceiveFrom(byteData, 0, byteData.Length, SocketFlags.None, ref epServer, new AsyncCallback(OnReceive), null);

} catch (SocketException)

Page 27: Bao Cao Mang Nang Cao

{ timer1.Enabled = false; MessageBox.Show("Server is not running or Port number is incorrect !!!", "Client", MessageBoxButtons.OK, MessageBoxIcon.Error); // btnCancel.Enabled = true; } catch (Exception ex1) { timer1.Enabled = false; MessageBox.Show(ex1.Message, "Client1", MessageBoxButtons.OK, MessageBoxIcon.Error); // btnCancel.Enabled = true; }

} //else //{ //MessageBox.Show("Dang nhap that bai","SERVERUDP");

//} }

private void OnSend(IAsyncResult ar) { try { clientSocket.EndSend(ar); } catch (Exception ex) { MessageBox.Show(ex.Message, "Client", MessageBoxButtons.OK, MessageBoxIcon.Error); } }

private void OnReceive(IAsyncResult ar) { try { clientSocket.EndReceive(ar); //Convert the bytes received into an object of type Data

Page 28: Bao Cao Mang Nang Cao

Data msgReceived = new Data(byteData);

//Accordingly process the message received switch (msgReceived.cmdCommand) { case Command.ACK: timer1.Enabled = false; DialogResult = DialogResult.OK; Close(); break; default: break; } } catch (ObjectDisposedException) { } catch (Exception ex) { MessageBox.Show(ex.Message, "Client", MessageBoxButtons.OK, MessageBoxIcon.Error); } } public static PhysicalAddress GetMacAddress(IPAddress ipAddress) { const int MacAddressLength = 6; int length = MacAddressLength; var macBytes = new byte[MacAddressLength]; SendARP(BitConverter.ToInt32(ipAddress.GetAddressBytes(), 0), 0, macBytes, ref length); return new PhysicalAddress(macBytes); }

private void txtIPserver_TextChanged(object sender, EventArgs e) { if ((txtIPserver.Text.Length > 0) && (txtPort.Text.Length > 0)) { btnOK.Enabled = true; } else { btnOK.Enabled = false; } }

private void txtPort_TextChanged(object sender, EventArgs e) { if ((txtIPserver.Text.Length > 0) && (txtPort.Text.Length > 0))

Page 29: Bao Cao Mang Nang Cao

{ btnOK.Enabled = true; } else { btnOK.Enabled = false; } }

}}

c. Class Data định nghĩa dữ liệu trao đổi Client và Serverusing System;using System.Collections.Generic;using System.Linq;using System.Text;

namespace Server{ // cau truc du lieu trao doi giua Client va Server class Data { //Default constructor public string strMac; //string MacAddress by which the client logs into Server public Command cmdCommand; //Command type (login, logout, send message, etcetera) public string strIP; //IP address

public Data() { this.cmdCommand = Command.Null; this.strMac = null; this.strIP = null; }

//Converts the bytes into an object of type Data public Data(byte[] data) { //The first four bytes are for the Command this.cmdCommand = (Command)BitConverter.ToInt32(data, 0);

//The next four store the length of the IPadd int msgLen = BitConverter.ToInt32(data, 4);

//The twelve bytes store MAC address this.strMac = Encoding.UTF8.GetString(data, 8, 12);

Page 30: Bao Cao Mang Nang Cao

//the nine bytes store IP address in which Server send to Old Client this.strIP = Encoding.UTF8.GetString(data, 20, msgLen);

}

//Converts the Data structure into an array of bytes public byte[] ToByte() { List<byte> result = new List<byte>();

//First four are for the Command result.AddRange(BitConverter.GetBytes((int)cmdCommand));

//Add the length of the IPadd result.AddRange(BitConverter.GetBytes(strIP.Length));

//Next we add the MAC add to our array of bytes result.AddRange(Encoding.UTF8.GetBytes(strMac));

// And, lastly we add IP address result.AddRange(Encoding.UTF8.GetBytes(strIP));

return result.ToArray(); } } }