[COLOR="#A52A2A"]
السلام عليكم اعضاء و زوار المنتدى ورحمة الله وبركاته ان شاء الله تكونوا في صحة وعافية
تكلمنا في موضوع Moving Complex Objects Across The Net عن كيفية نقل البيانات عبر الشبكة باستخدام بروتوكولات معينة
وتطرقنا ايضا عن كيفية نقل مجموعة مختلفة من البيانات ( int, float, double, string, ….. ) كوحدة واحدة (كحزمة واحدة) عبر الشبكة وقلنا ان افضل وسيلة لعمل ذلك هي باحتواء هذه البيانات في Class ومن ثم تحويل تلك البيانات الى Byte Array لكي يسهل لنا التعامل معها ونقلها عبر الشبكة.
الآن ماذا لو اردنا نقل كائن (فئة) مثلا نقل Class عبر الشبكة طبعا مع محتوياتها لكن بدون الحاجة لتحويل بياناتها الى حزمة واحدة وبدون الحاجة الى معرفة اطوال البيانات وإرسالها !!
كيف ذلك ؟
الحل هي بجعل الClass يمتلك خاصية ال Serialize,وذلك لكي نتمكن من تحويلها من كائن الى Stream Byte ونقلها عبر الشبكة.
اذا كيف نجعل الClass يمتلك خاصية الSerialize؟ (سنتطرق لها لاحقا ان شاء الله) وما هي الSerialize؟
الSerialize هي عملية تحويل كائن الى سلسلة من البايتات وخزنها في Stream ومن ثم كتابتها اما على ملف او لارسالها عبر الشبكة او خزنها في قاعدة البيانات.
وفرت لنا ال.NET فئتين للتعامل مع الSerialize
الاول : Binary Formatter ضمن مجال الاسماء System.Runtime.Serialization.Formatters.Binary
يقوم هذا الكلاس بتحويل الكائن الى Binary Encoding أي يقوم بعمل Serialize للكلاس عن طريق دالة الSerialize الى Stream اما لخزنها على القرص الصلب على شكل ملف bin او لنقلها عبر الشبكة.
الثاني : XmlSerializer ضمن مجال الاسماء System.Xml.Serialization
يقوم هذا الكلاس بتحويل الكائن الى XML Encoding عن طريق ايضا دالة الSerialize الى Stream اما لخزنها على شكل XML او نقلها عبر الشبكة .
ملاحظة// الملف الناتج من الSerialize يحتوي على البيانات التي عملنا لها Serialize + معلومات حول نوعية الكائن يتضمن (assembly name, culture, and version).
هنالك ثلاث متطلبات لعمل الSerialization
1-كائن لعمل Serialize لها.
2-Stream لاحتواء الكائن المسلسل (Serialized Object).
3-نوع الFormat المستخدم لعمل Serialize للكائن (Binary or Xml).
في هذا الموضوع ستكون الامثلة باستخدام الBinary Formatter وإذا اردت استخدام الXmlSerializer فقط استبدل مجال الاسماء مع اسم الكلاس ونوع الخزن (الامتداد) حيث يكون على شكل XML.
المثال الاول : عمل Serialize لكائن وكتابتها على ملف ثم استرجاع محتوى الكائن عن طريق الDeserialize
الكود بسيط ان شاء الله ومفهوم وليس هنالك داع لشرحها ,وتستطيع ارسالها عبر الشبكة عن طريق عمل Serialize للObject الى الNetworkStream.
المثال الثاني : سنقوم في هذا المثال بعمل Serialize ل Classو ارسالها عبر الشبكة ومن ثم استرجاعها عن طريق الDeserialize
ملاحظة// لكي يعمل الSerialized Class في الطرفين يجب ان نجعلها على شكل ملف مرجعي DLL ونقوم باستدعائها في كلا الجهتين.
ملاحظة// لعمل ملف مرجعي DLL يمكنك مراجعة هذا الموضوع: انشاء ملف dll بلغة C# الموجود موقعه في التوقيع
[COLOR="#A52A2A"]
اولا : نقوم ببناء Class Library كما اسلفنا طبعا يمكنك اختيار اسم المشروع بأي اسم آخر ونعطيه خاصية الSerialize هكذا:[/COLOR]
خاصية الSerialize [Serializable] الذي اعطيناها للClass يجعل من الClass قابل للكتابة والقراءة سواء الى ملف في القرص الصلب او الى Stream.
عندما نقوم بتنفيذ المشروع سينتج لنا ملف DLL في مخرجات المشروع (مجلدDebug ).
الان نقوم بنسخ هذا الملف و وضعها في مجلد الDebug للمرسل والمستلم ومن ثم نقوم بإضافته كمرجع لكلا الطرفين عن طريق
الAdd References ومن ثم استدعائها عن طريق الusing لكي نستطيع استخدام الSerialized Class في المشروع.
برنامج المرسل
اهم ما نستطيع ملاحظته في طرف المرسل هي في هذه الاسطر
في السطر الاول قمنا بإنشاء كائن جديد من نوع BinaryFormatter وفي السطر الثاني عملنا Serialize للكائن المراد ارساله الى Stream
عن طريق دالة الSerialize للكائن BinaryFormatter لإرسالها الى الطرف المستقبل.
برنامج المستقبل
الملاحظة المهمة في هذه الجهة تكمن ايضا في سطرين
في السطر الاول ايضا قمنا بإنشاء كائن من نوع BinaryFormatter ثم في السطر الثاني استرجعنا البيانات المرسلة عن طريق دالة الDeserialize
للكائن BinaryFormatter من الStream الى الكائن SerializeStdInfo.
[COLOR="#A52A2A"]وأخيرا اترك لكم اكتشاف الاختلاف بأنفسكم بين برنامجي المرسل والمستقبل في هذا الموضوع
وبرنامجي المرسل والمستقبل في موضوع ال Moving Complex Objects Across The Network
ملاحظة: مثالي المرسل والمستقبل في المرفقات
وفي الختام نحمد الله ونشكره لتوفيقه ايانا لكتابة هذا الموضوع والغاية هي افادة كل طالب علم ان شاءا لله ونصلي على رسوله الكريم محمد صلى الله عليه وآله وسلم ونسألكم الدعاء لي ولوالدي ولكل مسلم محتاج
[/COLOR]
بسم الله الرحمن الرحيم
((رب اشرح لي صدري ويسر لي امري واحلل عقدة من لساني يفقهوا قولي))
صدق الله العلي العظيم
[/COLOR]((رب اشرح لي صدري ويسر لي امري واحلل عقدة من لساني يفقهوا قولي))
صدق الله العلي العظيم
السلام عليكم اعضاء و زوار المنتدى ورحمة الله وبركاته ان شاء الله تكونوا في صحة وعافية
تكلمنا في موضوع Moving Complex Objects Across The Net عن كيفية نقل البيانات عبر الشبكة باستخدام بروتوكولات معينة
وتطرقنا ايضا عن كيفية نقل مجموعة مختلفة من البيانات ( int, float, double, string, ….. ) كوحدة واحدة (كحزمة واحدة) عبر الشبكة وقلنا ان افضل وسيلة لعمل ذلك هي باحتواء هذه البيانات في Class ومن ثم تحويل تلك البيانات الى Byte Array لكي يسهل لنا التعامل معها ونقلها عبر الشبكة.
الآن ماذا لو اردنا نقل كائن (فئة) مثلا نقل Class عبر الشبكة طبعا مع محتوياتها لكن بدون الحاجة لتحويل بياناتها الى حزمة واحدة وبدون الحاجة الى معرفة اطوال البيانات وإرسالها !!
كيف ذلك ؟
الحل هي بجعل الClass يمتلك خاصية ال Serialize,وذلك لكي نتمكن من تحويلها من كائن الى Stream Byte ونقلها عبر الشبكة.
اذا كيف نجعل الClass يمتلك خاصية الSerialize؟ (سنتطرق لها لاحقا ان شاء الله) وما هي الSerialize؟
الSerialize هي عملية تحويل كائن الى سلسلة من البايتات وخزنها في Stream ومن ثم كتابتها اما على ملف او لارسالها عبر الشبكة او خزنها في قاعدة البيانات.
وفرت لنا ال.NET فئتين للتعامل مع الSerialize
الاول : Binary Formatter ضمن مجال الاسماء System.Runtime.Serialization.Formatters.Binary
يقوم هذا الكلاس بتحويل الكائن الى Binary Encoding أي يقوم بعمل Serialize للكلاس عن طريق دالة الSerialize الى Stream اما لخزنها على القرص الصلب على شكل ملف bin او لنقلها عبر الشبكة.
الثاني : XmlSerializer ضمن مجال الاسماء System.Xml.Serialization
يقوم هذا الكلاس بتحويل الكائن الى XML Encoding عن طريق ايضا دالة الSerialize الى Stream اما لخزنها على شكل XML او نقلها عبر الشبكة .
ملاحظة// الملف الناتج من الSerialize يحتوي على البيانات التي عملنا لها Serialize + معلومات حول نوعية الكائن يتضمن (assembly name, culture, and version).
هنالك ثلاث متطلبات لعمل الSerialization
1-كائن لعمل Serialize لها.
2-Stream لاحتواء الكائن المسلسل (Serialized Object).
3-نوع الFormat المستخدم لعمل Serialize للكائن (Binary or Xml).
في هذا الموضوع ستكون الامثلة باستخدام الBinary Formatter وإذا اردت استخدام الXmlSerializer فقط استبدل مجال الاسماء مع اسم الكلاس ونوع الخزن (الامتداد) حيث يكون على شكل XML.
المثال الاول : عمل Serialize لكائن وكتابتها على ملف ثم استرجاع محتوى الكائن عن طريق الDeserialize
PHP كود :
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.IO;
using System.Runtime.Serialization.Formatters.Binary;
namespace SerializeDeserializeObject
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Serializebtn_Click(object sender, EventArgs e)
{
object o;
o = "sajad";
//Creating a new instance of class BinaryFormatter
BinaryFormatter bf = new BinaryFormatter();
//Creating stream to contain the serialized object
Stream s = new FileStream("sajad.bin", FileMode.Create, FileAccess.Write);
//Serializing an object into the stream
bf.Serialize(s, o);
//Close the stream
s.Close();
}
private void Deserializebtn_Click(object sender, EventArgs e)
{
//Creating a new instance of class BinaryFormatter
BinaryFormatter bf = new BinaryFormatter();
//Opening the stream for reading the serialized Object
Stream s = new FileStream("sajad.bin", FileMode.Open, FileAccess.Read);
//Deserializing the stream into an object
object o = (object)bf.Deserialize(s);
//Close the stream
s.Close();
//Show the deserialized data
MessageBox.Show(o.ToString());
}
}
}
الكود بسيط ان شاء الله ومفهوم وليس هنالك داع لشرحها ,وتستطيع ارسالها عبر الشبكة عن طريق عمل Serialize للObject الى الNetworkStream.
المثال الثاني : سنقوم في هذا المثال بعمل Serialize ل Classو ارسالها عبر الشبكة ومن ثم استرجاعها عن طريق الDeserialize
ملاحظة// لكي يعمل الSerialized Class في الطرفين يجب ان نجعلها على شكل ملف مرجعي DLL ونقوم باستدعائها في كلا الجهتين.
ملاحظة// لعمل ملف مرجعي DLL يمكنك مراجعة هذا الموضوع: انشاء ملف dll بلغة C# الموجود موقعه في التوقيع
[COLOR="#A52A2A"]
اولا : نقوم ببناء Class Library كما اسلفنا طبعا يمكنك اختيار اسم المشروع بأي اسم آخر ونعطيه خاصية الSerialize هكذا:[/COLOR]
PHP كود :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace StudentInfo
{
[Serializable] //This attribute makes the class ready for Serialization and Serializes all members of a class
//and tells the .NET Framework that the members on this class can be written to a file and read back from
public class SerializeStdInfo
{
public int id, age;
public double avg;
public string name, dept;
}
}
خاصية الSerialize [Serializable] الذي اعطيناها للClass يجعل من الClass قابل للكتابة والقراءة سواء الى ملف في القرص الصلب او الى Stream.
عندما نقوم بتنفيذ المشروع سينتج لنا ملف DLL في مخرجات المشروع (مجلدDebug ).
الان نقوم بنسخ هذا الملف و وضعها في مجلد الDebug للمرسل والمستلم ومن ثم نقوم بإضافته كمرجع لكلا الطرفين عن طريق
الAdd References ومن ثم استدعائها عن طريق الusing لكي نستطيع استخدام الSerialized Class في المشروع.
برنامج المرسل
PHP كود :
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.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Net.Sockets;
using System.Net;
using StudentInfo;
namespace SendAnObject
{
public partial class Form1 : Form
{
TcpClient client;
NetworkStream ns;
BinaryFormatter bf;
SerializeStdInfo stdinfo;
IPEndPoint iep;
public Form1()
{
InitializeComponent();
}
private void set_info()
{
//Creating a new intance of class SerializeStdInfo
stdinfo = new SerializeStdInfo();
stdinfo.id = int.Parse(idtxt.Text);
stdinfo.name = nametxt.Text;
stdinfo.age = int.Parse(agetxt.Text);
stdinfo.dept = depttxt.Text;
stdinfo.avg = double.Parse(avgtxt.Text);
}
private void sendbtn_Click(object sender, EventArgs e)
{
set_info();
//Creating end point
iep = new IPEndPoint(IPAddress.Parse("127.0.0.2"), 9000);
//Creating a new instance of class TcpClient
client = new TcpClient();
//Connecting to remote server
client.Connect(iep);
//Getting stream
ns = client.GetStream();
//Creating a new instance of class BinaryFormatter
bf = new BinaryFormatter();
//Serializing an object (Class) into the stream (NetworkStream)
bf.Serialize(ns, stdinfo);
//Close the Stream
ns.Close();
//Close the client
client.Close();
}
}
}
اهم ما نستطيع ملاحظته في طرف المرسل هي في هذه الاسطر
PHP كود :
//Creating a new instance of class BinaryFormatter
bf = new BinaryFormatter();
//Serializing an object (Class) into the stream (NetworkStream)
bf.Serialize(ns, stdinfo);
في السطر الاول قمنا بإنشاء كائن جديد من نوع BinaryFormatter وفي السطر الثاني عملنا Serialize للكائن المراد ارساله الى Stream
عن طريق دالة الSerialize للكائن BinaryFormatter لإرسالها الى الطرف المستقبل.
برنامج المستقبل
PHP كود :
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.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.Reflection;
using StudentInfo;
namespace ReceiveAnObject
{
public partial class Form1 : Form
{
Thread th;
TcpListener listen;
NetworkStream ns;
BinaryFormatter bf;
Socket sok;
SerializeStdInfo stdinfo;
public Form1()
{
InitializeComponent();
th = new Thread(new ThreadStart(Receive_Info));
th.Start();
}
private void get_info()
{
idtxt.Invoke(new MethodInvoker(delegate()
{
idtxt.Text = stdinfo.id.ToString();
}
));
///////////////////////////////////////////
nametxt.Invoke(new MethodInvoker(delegate()
{
nametxt.Text = stdinfo.name;
}
));
////////////////////////////////////////////
agetxt.Invoke(new MethodInvoker(delegate()
{
agetxt.Text = stdinfo.age.ToString();
}
));
///////////////////////////////////////////
depttxt.Invoke(new MethodInvoker(delegate()
{
depttxt.Text = stdinfo.dept;
}
));
////////////////////////////////////////////
avgtxt.Invoke(new MethodInvoker(delegate()
{
avgtxt.Text = stdinfo.avg.ToString();
}
));
///////////////////////////////////////////
label6.Invoke(new MethodInvoker(delegate()
{
label6.Text = "Data have been received!";
}
));
}
private void Receive_Info()
{
//Creating a new instance of class TcpListener
listen = new TcpListener(IPAddress.Any, 9000);
//Start Listening
listen.Start();
//Infinite loop
while (true)
{
//Accept the connecting
sok = listen.AcceptSocket();
//Creating a new instance of class NetworkStream
ns = new NetworkStream(sok);
//Creating a new instance of class BinaryFormatter
bf = new BinaryFormatter();
//Deserializing the Stream into the Object (Class)
stdinfo = (SerializeStdInfo)bf.Deserialize(ns);
//Getting the deserialized data
get_info();
//Release the stream
ns.Flush();
//Close the stream
ns.Close();
}
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
th.Abort();
listen.Stop();
}
}
}
الملاحظة المهمة في هذه الجهة تكمن ايضا في سطرين
PHP كود :
//Creating a new instance of class BinaryFormatter
bf = new BinaryFormatter();
//Deserializing the Stream into the Object (Class)
stdinfo = (SerializeStdInfo)bf.Deserialize(ns);
في السطر الاول ايضا قمنا بإنشاء كائن من نوع BinaryFormatter ثم في السطر الثاني استرجعنا البيانات المرسلة عن طريق دالة الDeserialize
للكائن BinaryFormatter من الStream الى الكائن SerializeStdInfo.
[COLOR="#A52A2A"]وأخيرا اترك لكم اكتشاف الاختلاف بأنفسكم بين برنامجي المرسل والمستقبل في هذا الموضوع
وبرنامجي المرسل والمستقبل في موضوع ال Moving Complex Objects Across The Network
ملاحظة: مثالي المرسل والمستقبل في المرفقات
وفي الختام نحمد الله ونشكره لتوفيقه ايانا لكتابة هذا الموضوع والغاية هي افادة كل طالب علم ان شاءا لله ونصلي على رسوله الكريم محمد صلى الله عليه وآله وسلم ونسألكم الدعاء لي ولوالدي ولكل مسلم محتاج
[/COLOR]