UDP-User Datagram Protocol- Encapsulation : 1.3.4
سوف نبين في هذا الجزء طبيعة الاتصال باستخدام الـ UDPحيث يتميز هذا البروتوآول
بإمكانية الإرسال آـ Multicastو Broadcastبعكس الـ TCPالذي يدعم الإرسال آـ Unicast
فقط ، لاآن مشكلة هذا البروتوآول هو عدم دعمه لعمليات التحكم على مستوى Data
Flowأو حجم الـ Bufferآما لا يدعم عمليات التحقق من الوصول وفق الترتيب السليم
Delivered on Sequenceوتعتبر هذه الأمور من أهم عيوبه ويوضح الشكل التالي الترآيب
العام لهذا البروتوكول:
الـ Check Sumو الـ Lengthأو الـ Header Lengthهي نفسها في الـ TCPلاآن لاحظ عدم
فيDelivered On Sequence أو الـBuffer Managementوجود أي من الأمور الخاصة بالـ
الـ Headerالخاص بالـ ، UDPوالمشكلة هنا أننا لا نستطيع عمل FragmentationللـPackets
حيث أن إعادة تجميعها بالترتيب الصحيح أمر غير مضمون، آما أنه لا وجود لأي
Acknowledgmentلتحقق من وصول البيانات ، الشكل التالي يوضح طبيعة التراسل
باستخدام الـ: UDP
في المثال التالي يتم فتح الـ5020 Portوالتصنت عليها ثم استلام الرسالة عبر هذا الـ Port
وتوزيعها على الكل:
C#:
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 5020);
وتتم عملية إنشاء الـ Socketوتحديد نوع البرتوآول المستخدم آما يلي:
C#:
Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram,
ProtocolType.Udp)
... Send إلى الميثودIPEndpoint Object ثم نمرر
في الـ Bind Methodوالتي يتم وضعها في الطرف المستقبل فقط يتم استخدامها لربط الـ
: Socket بالـPort ورقم الـIP Address
C#:
newsock.Bind(ipep);
الآن تم استقبال الرسالة ونريد بثها إلى آل من يتصل مع الـ Serverعلى الـ Portالسابقة
ولعمل ذلك يلزم أولا تعريف IPEndPoint Objectآما يلي :
C#:
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
EndPoint Remote = (EndPoint)(sender);
لاحظ أن العنوان المسند إلى IPEndPoint Objectهو Anyورقم ال Portصفر وهذا يعني
إرسال الرسالة المستلمة إلى الكل وبما فيهم الشخص مرسل الرسالة و الـ: Server
C#:
recv = newsock.ReceiveFrom(data, ref Remote);
لطباعة عنوان مرسل الرسالة و الرسالة نفسها:
C#:
Console.WriteLine("Message received from {0}:", Remote.ToString());
Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
لطباعة عنوان مرسل الرسالة و الرسالة نفسها:
C#:
Console.WriteLine("Message received from {0}:", Remote.ToString());
Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
الهدف من الـ : Infinity Loopعند استقبال أي رسالة في أي وقت من قبل أي جهاز حيث
يقوم الـ Serverباستلامها وتسليمها إلى آل من هو على الشبكة ... إذا أردت تحديد عدد
معين من الرسائل المستلمة تستطيع تغيير الـ Trueفي الـ infinity loopإلى أي رقم
تريده..
C#:
while(true)
{
data = new byte[1024];
recv = newsock.ReceiveFrom(data, ref Remote);
Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
newsock.SendTo(data, recv, SocketFlags.None, Remote);
}
server.Close();
يتم هنا إغلاق الـ Socketفي حالة إذا تم الخروج من Infinity Loopو لن يتم الوصول إلى
هذه النقطة إلا إذا تم مقاطعته بوضع Breakضمن الـ Infinity Loopوفق شرط معين أي انه
في حالة استقبال رسالة أو نص رسالة معينة سيتم الخروج من الـ Loopوسيتم إغلاق الـ
Socketوهذا يعني انك تستطيع إغلاق الـ Serverعن بعد آما يمكنك وضع جملة تشغيل
أي ملف تنفيذي على ال Serverفي حالة ورود نص معين وهكذا .
وسوف اعرض المثال الكامل لعملية الإرسال عبر الـ، UDp
أولا الجزء الخاص بالـ: Server
C#:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
class SimpleUdpSrvr
{
public static void Main()
{
int recv;
byte[] data = new byte[1024];
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 5020);
Socket newsock = new Socket(AddressFamily.InterNetwork,
SocketType.Dgram, ProtocolType.Udp);
newsock.Bind(ipep);
Console.WriteLine("Waiting for a client...");
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
EndPoint Remote = (EndPoint)(sender);
recv = newsock.ReceiveFrom(data, ref Remote);
Console.WriteLine("Message received from {0}:", Remote.ToString());
Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
string welcome = " Welcome Customer ...";
data = Encoding.ASCII.GetBytes(welcome);
newsock.SendTo(data, data.Length, SocketFlags.None, Remote);
while (true)
{
data = new byte[1024];
recv = newsock.ReceiveFrom(data, ref Remote);
Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
newsock.SendTo(data, recv, SocketFlags.None, Remote);
}
}
}
ثانيا الجزء الخاص بالـ ، Clientيقتصر العمل على قيام الـ Clientبإنشاء جلسة مع الServer
وذلك بعد تعريفه بالـ IPEndPointورقم ال Portوآما تم في السابق إلا أن الاختلاف هو في
الوظيفة إذا يقتصر فقط على استقبال الرسالة من ال Serverوإرسال أي رساله له عبر
ال Portالمخصص :
C#:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
class SimpleUdpClient
{
public static void Main()
{
byte[] data = new byte[1024]; string input, stringData;
IPEndPoint ipep = new IPEndPoint( IPAddress.Parse("127.0.0.1"), 5020);
Socket server = new Socket(AddressFamily.InterNetwork,SocketType.Dgram,
ProtocolType.Udp);
في حالة فقدان الاتصال مع ال Serverيظهر الرسالة التالية :
string welcome = "Hello, are you there?";
data = Encoding.ASCII.GetBytes(welcome);
server.SendTo(data, data.Length, SocketFlags.None, ipep);
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
EndPoint Remote = (EndPoint)sender;
data = new byte[1024];
int recv = server.ReceiveFrom(data, ref Remote);
Console.WriteLine("Message received from {0}:", Remote.ToString());
Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
while(true)
{
input = Console.ReadLine();
في حالة إذا أردت إنهاء الجلسة اآتب Exit
if (input == "exit")
break;
server.SendTo(Encoding.ASCII.GetBytes(input), Remote);
data = new byte[1024];
recv = server.ReceiveFrom(data, ref Remote);
stringData = Encoding.ASCII.GetString(data, 0, recv);
Console.WriteLine(stringData);
}
Console.WriteLine("Stopping client");
server.Close();
}
}
سوف نبين في هذا الجزء طبيعة الاتصال باستخدام الـ UDPحيث يتميز هذا البروتوآول
بإمكانية الإرسال آـ Multicastو Broadcastبعكس الـ TCPالذي يدعم الإرسال آـ Unicast
فقط ، لاآن مشكلة هذا البروتوآول هو عدم دعمه لعمليات التحكم على مستوى Data
Flowأو حجم الـ Bufferآما لا يدعم عمليات التحقق من الوصول وفق الترتيب السليم
Delivered on Sequenceوتعتبر هذه الأمور من أهم عيوبه ويوضح الشكل التالي الترآيب
العام لهذا البروتوكول:
الـ Check Sumو الـ Lengthأو الـ Header Lengthهي نفسها في الـ TCPلاآن لاحظ عدم
فيDelivered On Sequence أو الـBuffer Managementوجود أي من الأمور الخاصة بالـ
الـ Headerالخاص بالـ ، UDPوالمشكلة هنا أننا لا نستطيع عمل FragmentationللـPackets
حيث أن إعادة تجميعها بالترتيب الصحيح أمر غير مضمون، آما أنه لا وجود لأي
Acknowledgmentلتحقق من وصول البيانات ، الشكل التالي يوضح طبيعة التراسل
باستخدام الـ: UDP
في المثال التالي يتم فتح الـ5020 Portوالتصنت عليها ثم استلام الرسالة عبر هذا الـ Port
وتوزيعها على الكل:
C#:
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 5020);
وتتم عملية إنشاء الـ Socketوتحديد نوع البرتوآول المستخدم آما يلي:
C#:
Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram,
ProtocolType.Udp)
... Send إلى الميثودIPEndpoint Object ثم نمرر
في الـ Bind Methodوالتي يتم وضعها في الطرف المستقبل فقط يتم استخدامها لربط الـ
: Socket بالـPort ورقم الـIP Address
C#:
newsock.Bind(ipep);
الآن تم استقبال الرسالة ونريد بثها إلى آل من يتصل مع الـ Serverعلى الـ Portالسابقة
ولعمل ذلك يلزم أولا تعريف IPEndPoint Objectآما يلي :
C#:
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
EndPoint Remote = (EndPoint)(sender);
لاحظ أن العنوان المسند إلى IPEndPoint Objectهو Anyورقم ال Portصفر وهذا يعني
إرسال الرسالة المستلمة إلى الكل وبما فيهم الشخص مرسل الرسالة و الـ: Server
C#:
recv = newsock.ReceiveFrom(data, ref Remote);
لطباعة عنوان مرسل الرسالة و الرسالة نفسها:
C#:
Console.WriteLine("Message received from {0}:", Remote.ToString());
Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
لطباعة عنوان مرسل الرسالة و الرسالة نفسها:
C#:
Console.WriteLine("Message received from {0}:", Remote.ToString());
Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
الهدف من الـ : Infinity Loopعند استقبال أي رسالة في أي وقت من قبل أي جهاز حيث
يقوم الـ Serverباستلامها وتسليمها إلى آل من هو على الشبكة ... إذا أردت تحديد عدد
معين من الرسائل المستلمة تستطيع تغيير الـ Trueفي الـ infinity loopإلى أي رقم
تريده..
C#:
while(true)
{
data = new byte[1024];
recv = newsock.ReceiveFrom(data, ref Remote);
Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
newsock.SendTo(data, recv, SocketFlags.None, Remote);
}
server.Close();
يتم هنا إغلاق الـ Socketفي حالة إذا تم الخروج من Infinity Loopو لن يتم الوصول إلى
هذه النقطة إلا إذا تم مقاطعته بوضع Breakضمن الـ Infinity Loopوفق شرط معين أي انه
في حالة استقبال رسالة أو نص رسالة معينة سيتم الخروج من الـ Loopوسيتم إغلاق الـ
Socketوهذا يعني انك تستطيع إغلاق الـ Serverعن بعد آما يمكنك وضع جملة تشغيل
أي ملف تنفيذي على ال Serverفي حالة ورود نص معين وهكذا .
وسوف اعرض المثال الكامل لعملية الإرسال عبر الـ، UDp
أولا الجزء الخاص بالـ: Server
C#:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
class SimpleUdpSrvr
{
public static void Main()
{
int recv;
byte[] data = new byte[1024];
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 5020);
Socket newsock = new Socket(AddressFamily.InterNetwork,
SocketType.Dgram, ProtocolType.Udp);
newsock.Bind(ipep);
Console.WriteLine("Waiting for a client...");
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
EndPoint Remote = (EndPoint)(sender);
recv = newsock.ReceiveFrom(data, ref Remote);
Console.WriteLine("Message received from {0}:", Remote.ToString());
Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
string welcome = " Welcome Customer ...";
data = Encoding.ASCII.GetBytes(welcome);
newsock.SendTo(data, data.Length, SocketFlags.None, Remote);
while (true)
{
data = new byte[1024];
recv = newsock.ReceiveFrom(data, ref Remote);
Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
newsock.SendTo(data, recv, SocketFlags.None, Remote);
}
}
}
ثانيا الجزء الخاص بالـ ، Clientيقتصر العمل على قيام الـ Clientبإنشاء جلسة مع الServer
وذلك بعد تعريفه بالـ IPEndPointورقم ال Portوآما تم في السابق إلا أن الاختلاف هو في
الوظيفة إذا يقتصر فقط على استقبال الرسالة من ال Serverوإرسال أي رساله له عبر
ال Portالمخصص :
C#:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
class SimpleUdpClient
{
public static void Main()
{
byte[] data = new byte[1024]; string input, stringData;
IPEndPoint ipep = new IPEndPoint( IPAddress.Parse("127.0.0.1"), 5020);
Socket server = new Socket(AddressFamily.InterNetwork,SocketType.Dgram,
ProtocolType.Udp);
في حالة فقدان الاتصال مع ال Serverيظهر الرسالة التالية :
string welcome = "Hello, are you there?";
data = Encoding.ASCII.GetBytes(welcome);
server.SendTo(data, data.Length, SocketFlags.None, ipep);
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
EndPoint Remote = (EndPoint)sender;
data = new byte[1024];
int recv = server.ReceiveFrom(data, ref Remote);
Console.WriteLine("Message received from {0}:", Remote.ToString());
Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
while(true)
{
input = Console.ReadLine();
في حالة إذا أردت إنهاء الجلسة اآتب Exit
if (input == "exit")
break;
server.SendTo(Encoding.ASCII.GetBytes(input), Remote);
data = new byte[1024];
recv = server.ReceiveFrom(data, ref Remote);
stringData = Encoding.ASCII.GetString(data, 0, recv);
Console.WriteLine(stringData);
}
Console.WriteLine("Stopping client");
server.Close();
}
}