Tải bản đầy đủ (.doc) (27 trang)

Lập trình UDP socket giao tiếp client server

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (430.36 KB, 27 trang )

Đạ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
Phạm Thu Hường
Nguyễn Ngọc Kiều

ĐT8 - K52

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

20071475


Mục lục

Contents
Contents......................................................................................................................................................2


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


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 OSI
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 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


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


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 port
Trườ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 port
Trường xác định cổng nhận thông tin, và trường này là cần thiết.
Length
Trườ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.
2
Trườ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


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.
 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
 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ình
1. Giao diện
a. Server
• Chưa có client kết nối

• Có Client kết nối

b. Client





Login



Form chính

2. Chương trình
a. Server
using System;
using System.Collections;
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;
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
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");
//
_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;
// 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
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;
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;
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);
//}
}
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
{
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;
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;
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.
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;
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()
{
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. Client
using 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
{


[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
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)
{
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
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);


×