Lập trình UDP socket giao tiếp client server
Trang 1Đạ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 :
Phạm Thu Hường
Nguyễn Ngọc Kiều
Hà Nội, tháng 10 năm 2011
Trang 2Mục lục
Contents
Contents 2
Trang 3Yê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 haychư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ốicầ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ề clientmớ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ếtnối vào server
Trang 4I 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
Trang 5Mộ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 OSIluô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
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
Trang 6UDP 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)
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ữnggiao 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ầnthiế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óicá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
Trang 7như 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 chocá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 ứngdụ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á
Trang 8trì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ứcmạ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ệ
Trang 10Login, //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
{
Trang 11//
// 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
// dinh nghia mot byteData
byte[] byteData = new byte[1024];
// flag quiting dung cho viec Stop server
// 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());
Trang 12toolTip1.SetToolTip(comboBox1, "IP address Server");
toolTip1.SetToolTip(txtPort, "Port number in which Server is listening"); //
// 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;
Trang 13// 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
// Doi text Button1 thanh Start Server
button1.Text = "Start Server";
toolTip1.SetToolTip(this.button1, "Click to Start Server ");
// Set flag StartSer ve false
Trang 14// 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
// bat loi Stop server o day => tham khao tren mang
IPEndPoint ipeSender = new IPEndPoint(IPAddress.Any, 0); EndPoint epSender = (EndPoint)ipeSender;
//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)
Trang 16SocketFlags.None, ref epSender,
new AsyncCallback(OnReceive), epSender);
Trang 17if (MessageBox.Show("Port number incorrect !", "ServerUDP",
MessageBoxButtons.RetryCancel, MessageBoxIcon.Error) == DialogResult.Retry) {
//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
Trang 18}
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();
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),
DialogResult dialogResult = form.ShowDialog();
//Regex rex = new Regex(@"^[0-9]\w{3,4}$");
Trang 19//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",
Trang 20// 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
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
sIP = line.Substring(0, line.IndexOf("#"));
sMac = line.Substring(line.IndexOf("#") + 1, line.Length - line.IndexOf("#")
Trang 21MessageBox.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); }
Trang 22
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("#")
Trang 23[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;
// 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,
Trang 24// 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();
byteData = new byte[1024];
//Start listening to the data asynchronously
Trang 25//Convert the bytes received into an object of type Data
Data msgReceived = new Data(byteData);
//Accordingly process the message received
Trang 26}
}
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);
Trang 27public Command cmdCommand; //Command type (login, logout, send message, etcetera)
public string strIP; //IP address
//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);
//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