منتدى فيجوال بيسك لكل العرب | منتدى المبرمجين العرب
Moving Complex Objects Across The Net Using Serlialization - نسخة قابلة للطباعة

+- منتدى فيجوال بيسك لكل العرب | منتدى المبرمجين العرب (http://vb4arb.com/vb)
+-- قسم : قسم لغة السي شارب C#.NET (http://vb4arb.com/vb/forumdisplay.php?fid=175)
+--- قسم : قسم مقالات C#.NET (http://vb4arb.com/vb/forumdisplay.php?fid=177)
+--- الموضوع : Moving Complex Objects Across The Net Using Serlialization (/showthread.php?tid=8104)



Moving Complex Objects Across The Net Using Serlialization - Sajad - 23-03-13

[COLOR="#A52A2A"]
بسم الله الرحمن الرحيم
((رب اشرح لي صدري ويسر لي امري واحلل عقدة من لساني يفقهوا قولي))
صدق الله العلي العظيم
[/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 senderEventArgs e
        { 
            
object 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.CreateFileAccess.Write); 
            
//Serializing an object into the stream 
            
bf.Serialize(so); 
            
//Close the stream 
            
s.Close(); 
        } 

        private 
void Deserializebtn_Click(object senderEventArgs 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.OpenFileAccess.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 idage
        public 
double avg
        public 
string namedept
    } 



خاصية ال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 senderEventArgs 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(nsstdinfo); 
            
//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(nsstdinfo); 

في السطر الاول قمنا بإنشاء كائن جديد من نوع 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.Any9000); 
            
//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 senderFormClosedEventArgs 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]



Moving Complex Objects Across The Net Using Serlialization - @@أبورائد@@ - 23-03-13




السلام عليكم ورحمة الله وبركاته





ما شاء الله تبارك الله لا قوة إلا بالله

أشكرك أخي الأستاذ سجــّــــــــــــــــــــــــــــــاد
ربنا يزيدك من فضله




السلام عليكم ورحمة الله وبركاته



Moving Complex Objects Across The Net Using Serlialization - Sajad - 23-03-13

وعليكم السلام ورحمة الله اخي العزيز

شكرا على المرور والتعليق بارك الله فيك اتمنى ان تستفيد من الموضوعSmile

ان شاءالله سأحول الامثلة الى لغة الvb.net وسأرفقها في هذا الموضوع




Moving Complex Objects Across The Net Using Serlialization - Sajad - 23-03-13

السلام عليكم

الامثلة بلغة الvb.net في المرفقات

بالتوفيق ان شاءالله