fmo_82

سلسلة دروس C# Network Programming

237 ردود في هذا الموضوع

ثانيا: Remotting Programming :

يعتبر موضوع الـ Remotting من المواضيع الهامة جدا في برمجة الشبكات , إذ يقدم لنا إمكانيات رائعة في مشاركة و استخدام الـ Remote Methods والموجودة على الـ Remote Server وتشبه عملية التعامل مع الـ Remotting عملية الـ Web Services إلى حد كبير حيث يتطلب استخدامها عمل Proxy Object في طرف الـClient, لكن مع إمكانيات اكبر حيث تقوم بإنشاء الـServer بنفسك ولست مضطرا لتثبيت

الـ IIS أو غيره من التطبيقات الوسيطة للاستفادة من خدمات الـ Remote Server , وتستطيع من خلاله تنفيذ أي عملية معالجة على الـ Server مما يعزز من مبدأ الـ Distributed Systems والذي شرحناه في الجزء الأول من هذا الفصل حيث تبقى الـ methods و عملية المعالجة الخاصة بها على الـ Server في حين يتم إرسال الـ Result إلى الـ Clients كـ XML Data أو Binary Data حسب قناة الاتصال المستخدمة سواء HttpChannel أو TcpChannel , وتمرر إلى الـ Client عبر الـ Proxy Object والذي ربط الـ Remote Class الموجود على الـ Server مع الـ Client لاحظ الشكل التالي:

04_05_06_10_17_29_1146763049dotnet_remoting.gif

1- Using Remotting in Dot Net :

يمكن استخدام الـ Remotting بطريقتين الأولى عبر بروتوكول الـ HTTP حيث تتم عملية التراسل كـ XML Data بين الـ Server والـ Clients وتتم باستخدام بروتوكول

الـ SOAP أما الطريقة الثانية فتتم باستخدام الـ TCP Protocol حيث تكون عملية التراسل كـ Binary Data بين الـ Server وبقية الـ Clients , ويفضل دائما استخدام

الـ TCP Channel في الحالتين التاليتين:

الأولى: إذا كانت قناة الاتصال سريعة نسبيا

الثانية: توافقية البيئات حيث تستخدم نظام التشغيل Microsoft Windows في جميع الـ clients , ويعتبر هذه الأمر من أهم عيوب استخدام الـ TCP Channel وخاصة في حالة الـWeb حيث لا تضمن البيئة التي سيعمل عليها الـ Client ويفضل في هذه الحالة استخدام الـ HTTP Channel , لكن تبقى أدائية الـ TCP Channel أفضل من الـ HTTP ...

وما يميز الـ HTTP Channel هو استخدامه بروتوكول الـ SOAP والذي يتعامل مع الـXML في عملية التراسل مما يضمن توافقيته مع جميع البيئات.

يلزم استخدام الـ Remotting في الدوت نيت ثلاثة أمور :

أولا, تحديد طبيعة القناة المستخدمة سواء عبر الـ HTTP كـXML أو عبر الـ TCP كـBinary Formatter ودعمت الدوت نيت كلا منهما في الـClass HttpChannel والموجود ضمن System.Runtime.Remoting.Channels.Http Namespace والـTcpChannel Class والموجود ضمن الـ System.Runtime.Remoting.Channels.Tcp Namespace (يجب إضافته إلى الـ References في المشروع), حيث يجب تعريفها في كلا الطرفين الـ Client والـ Server وكما يلي:

C#:
HttpChannel http_Channel = new HttpChannel(Port_Number);

VB.NET:
Dim http_Channel As HttpChannel = New HttpChannel(Port_Number)

وفي حالة استخدام الـ TcpChannel كما يلي:

C#:
TcpChannel Tcp_Channel = new TcpChannel(Port_Number);

VB.NET:
Dim Tcp_Channel As TcpChannel = New TcpChannel(Port_Number)

بعد ذلك يجب تسجيل القناة المستخدمة باستخدام الميثود RegisterChannel والموجودة ضمن الـ ChannelServices Class ضمن الـSystem.Runtime.Remoting.Channels Namespace , ويتم ذلك في كلا الطرفين أيضا الـ Client والـ Server وكما يلي:

C#:
ChannelServices.RegisterChannel(chan);

VB.NET:
ChannelServices.RegisterChannel(chan)

بعد ذلك يجب تعريف الـ Class الذي سيتم مشاركته على الـ Server ويتم ذلك باستخدام الميثود RegisterWellKnownServiceType والموجودة ضمن الـ RemotingConfiguration Class والموجود ضمن الـ System.Runtime.Remoting Namespace ويتم ذلك كما يلي في طرف الـ Server:

C#:
RemotingConfiguration.RegisterWellKnownServiceType (Type.GetType ("Class_File_Name, Distributed_Class_Name"), "unique_Service_Name", WellKnownObjectMode.SingleCall);

VB.NET:
RemotingConfiguration.RegisterWellKnownServiceType (Type.GetType ("Class_File_Name, Distributed_Class_Name"), "unique_Service_Name", WellKnownObjectMode.SingleCall)

وتأخذ الـ RegisterWellKnownServiceType Method ثلاثة باروميترات الأول الـType الخاص باسم الـ Remote Class مع اسم الـ Dll File ومساره والذي نريد توزيعه ويأخذ الباروميتر الثاني اسم الـ URI الخاص بالـ Object الذي نريد توزيعه ويجب أن يكون

الـ URI Object اسم فريد unique على مستوى الـ Application Port , ويأخذ الباروميتر الثالث نوع الـ Remote Instance Object فإذا تم اختيار SingleCall فهذا يعني إنشاء New Instance جديد لكل Client يقوم بإنشاء Instance من الـ Remote Class ,

وإذا تم اختيار Singleton فهذا يعني استخدام نفس الـ Remote Instance Object لكل الـ Clients , وينصح استخدام SingleCall في حالة كان النظام الموزع سيستخدم Session لكل User وينصح باستخدام Singleton في حالة كان الـ Server سيبث نفس المعلومات إلى كل الـ Clients على الشبكة...

أما في الـ Client فيجب تعريف نوع الـ Channel سواء TCP أو HTTP Channel حسب نوع القناة التي تم استخدمها في الـ Server ولا يتم وضع رقم الـ Port في الـ Client Channel ونكتفي بوضعه في الـ URI Object ويتم تعريف القناة في الـ Client كما يلي:

C#:
HttpChannel http_Channel = new HttpChannel

VB.NET:
Dim http_Channel As HttpChannel = New HttpChannel()

وفي حالة استخدام الـ TcpChannel كما يلي:

C#:
TcpChannel Tcp_Channel = new TcpChannel();

VB.NET:
Dim Tcp_Channel As TcpChannel = New TcpChannel()

ويتم تسجيل القناةRegisterChannel في الـ Client كما هو الحال في الـ Server وكما يلي:

C#:
ChannelServices.RegisterChannel(chan);

VB.NET:
ChannelServices.RegisterChannel(chan)

بعد ذلك نقوم بتعريف New Instance Object من الـ Remote Client حيث يجب أن يحتوي الـ Client Project على الـ Dll File الخاص بالـ Distributed Class حيث نقوم في البداية بتعريف الـ URI والذي سيحتوي على الـ Protocol المستخدم ويتبع بعنوان الجهاز أو الـ DNS الخاص بالـ Server ومن ثم رقم الـ Port المستخدم و اسم الخدمة التي تم تعريفها في الـ Server ويتم ذلك كما يلي:

في حالة استخدام TCP Channel :

C#:
string URI = "Tcp://"+Remote_IP.Text+":Port/ unique_Service_Name ";

VB.NET:
Dim URI As String = "Tcp://" & Remote_IP.Text & ": Port/ unique_Service_Name "

في حالة استخدام HTTP Channel :

C#:
string URI = "Http://"+Remote_IP.Text+": Port / unique_Service_Name";

VB.NET:
Dim URI As String = " Http://" & Remote_IP.Text & ": Port / unique_Service_Name "

وبعد ذلك نقوم بإنشاء New Instance Object من الـ Remote Class ويتم ذلك باستخدام الـ GetObject Method والموجود ضمن الـ Activator Class ونمرر لها

الـ Distributed Class Type و الـ URI الذي عرفناه , وكما يلي:

C#:
Distributed_Class_Name obj = (Distributed_Class_Name) Activator.GetObject
(typeof (Distributed_Class_Name), URI);

VB.NET:
Dim obj As Distributed_Class_Name = CType(Activator.GetObject(GetType(Distributed_Class_Name), URI), Distributed_Class_Name)

ملاحظة هامة جدا:

يجب أن يتم توريث الـ MarshalByRefObject Class إلى الـ Distributed Class الذي نريد توزيعه والموجود ضمن System Namespace وعند توريث الـ MarshalByRefObject إلى الـ Distributed Class سيتم تنفيذ كافة العمليات أو الـ Process على الـ Server وسيحصل الـ Client على الـ Result النهائي في حين إذا تم استخدام الـMarshalByValueObject عندها سيتم استخدام الـ Remote Class و لكن ستتم عملية المعالجة على الـ Client Side ...

وهكذا بينا كيفية استخدام الـ Remotting في الدوت نيت , سنقوم الآن بتطبيق هذه المفاهيم في مشروع حيث سنقوم بإنشاء Distributed Class يقوم بعملية التقاط لصورة سطح المكتب الخاص بالـ Server وبثها إلى الـ Client مستخدما الـ TcpChannel بين الـ Server والـ Client وسنفترض في هذا المثال إنشاء Remote Classroom حيث يقوم المعلم بإلقاء محاضرة إلى طلابه ويتم بث صورة الكاميرا وسطح المكتب الخاص بالمعلم عبر الإنترنت إلى الطلاب في الـ Classroom والموجودين في دول متعددة وكما في الشكل التالي:

04_05_06_10_18_44_1146763124Remotting_Classrooms.JPG

سنستخدم في هذا المثال الـ TCP Channel والـ HttpChannel وسنقارن الأداء في كل منهما ,برنامج المحاضر (Lecturer Project) وسيكون الشكل العام له كما هو مبين في الشكل التالي حيث:

04_05_06_10_19_28_1146763168Remotting_Server.JPG

برنامج الـ Client ويمكن أن يكون من خلال الإنترنت في حالة كان لديك Real IP أو

في الشبكة المحلية وكما هو مبين في الشكل التالي:

04_05_06_10_21_24_1146763284Remotting_Client.JPG

ولإنشاء الـ Remote Class والذي سيقوم بجلب صورة سطح المكتب , سنستخدم دوال الـ API ومنها الـ GetDesktopWindow Method والموجودة ضمن الـuser32.dl والـ BitBlt Method لرسم الصورة , ثم سنقوم بتحويل الصورة إلى Byte Array وحتى نستطيع إرسالها إلى الـ Clients , وبتأكيد سنستخدم طريقة MarshalByRefObject وحتى تتم عملية التقاط ومعالجة الصورة على الـ Server Side , ويتم ذلك كما يلي :

C#:
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.IO;

public class ScreenCapture : System.MarshalByRefObject
{
[DllImport("user32.dll")]
private static extern IntPtr GetDesktopWindow();

[DllImport("gdi32.dll")]
private static extern bool BitBlt(
IntPtr hdcDest, // handle to destination DC
int nXDest, // x-coord of destination upper-left corner
int nYDest, // y-coord of destination upper-left corner
int nWidth, // width of destination rectangle
int nHeight, // height of destination rectangle
IntPtr hdcSrc, // handle to source DC
int nXSrc, // x-coordinate of source upper-left corner
int nYSrc, // y-coordinate of source upper-left corner
System.Int32 dwRop // raster operation code
);

private const Int32 SRCCOPY = 0xCC0020;
[DllImport("user32.dll")]
private static extern int GetSystemMetrics(int nIndex);

private const int SM_CXSCREEN = 0;
private const int SM_CYSCREEN = 1;

public Size GetDesktopBitmapSize()
{
return new Size(GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
}

public byte[] GetDesktopBitmapBytes()
{
Size DesktopBitmapSize = GetDesktopBitmapSize();
Graphics Graphic = Graphics.FromHwnd(GetDesktopWindow());
Bitmap MemImage = new Bitmap(DesktopBitmapSize.Width, DesktopBitmapSize.Height, Graphic);
Graphics MemGraphic = Graphics.FromImage(MemImage);
IntPtr dc1 = Graphic.GetHdc();
IntPtr dc2 = MemGraphic.GetHdc();
BitBlt(dc2, 0, 0, DesktopBitmapSize.Width, DesktopBitmapSize.Height, dc1, 0, 0, SRCCOPY);
Graphic.ReleaseHdc(dc1);
MemGraphic.ReleaseHdc(dc2);
Graphic.Dispose();
MemGraphic.Dispose();

Graphics g = System.Drawing.Graphics.FromImage(MemImage);
System.Windows.Forms.Cursor cur = System.Windows.Forms.Cursors.Arrow;
cur.Draw(g,new Rectangle(System.Windows.Forms.Cursor.Position.X-10,System.Windows.Forms.Cursor.Position.Y-10,cur.Size.Width,cur.Size.Height));

MemoryStream ms = new MemoryStream();
MemImage.Save(ms,System.Drawing.Imaging.ImageFormat.Jpeg);
return ms.GetBuffer();
}

}

VB.NET
Imports System
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.Runtime.InteropServices
Imports System.IO

Public Class ScreenCapture : Inherits System.MarshalByRefObject
   <DllImport("user32.dll")> _
   Private Shared Function GetDesktopWindow() As IntPtr
   End Function

   <DllImport("gdi32.dll")> _
   Private Shared Function BitBlt(ByVal hdcDest As IntPtr, ByVal nXDest As Integer, ByVal nYDest As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal hdcSrc As IntPtr, ByVal nXSrc As Integer, ByVal nYSrc As Integer, ByVal dwRop As System.Int32) As Boolean
   End Function

   Private Const SRCCOPY As Int32 = &HCC0020
   <DllImport("user32.dll")> _
Private Shared Function GetSystemMetrics(ByVal nIndex As Integer) As Integer
End Function

Private Const SM_CXSCREEN As Integer = 0
Private Const SM_CYSCREEN As Integer = 1
Public Function GetDesktopBitmapSize() As Size
Return New Size(GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN))
   End Function

   Public Function GetDesktopBitmapBytes() As Byte()
       Dim DesktopBitmapSize As Size = GetDesktopBitmapSize()
       Dim Graphic As Graphics = Graphics.FromHwnd(GetDesktopWindow())
       Dim MemImage As Bitmap = New Bitmap(DesktopBitmapSize.Width, DesktopBitmapSize.Height, Graphic)
       Dim MemGraphic As Graphics = Graphics.FromImage(MemImage)
       Dim dc1 As IntPtr = Graphic.GetHdc()
       Dim dc2 As IntPtr = MemGraphic.GetHdc()
       BitBlt(dc2, 0, 0, DesktopBitmapSize.Width, DesktopBitmapSize.Height, dc1, 0, 0, SRCCOPY)
       Graphic.ReleaseHdc(dc1)
       MemGraphic.ReleaseHdc(dc2)
       Graphic.Dispose()
       MemGraphic.Dispose()

Dim g As Graphics = System.Drawing.Graphics.FromImage(MemImage)
Dim cur As System.Windows.Forms.Cursor = System.Windows.Forms.Cursors.Arrow
cur.Draw(g, New Rectangle(System.Windows.Forms.Cursor.Position.X - 10, System.Windows.Forms.Cursor.Position.Y - 10, cur.Size.Width, cur.Size.Height))

Dim ms As MemoryStream = New MemoryStream
MemImage.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg)
Return ms.GetBuffer()
   End Function
End Class

وبتأكيد يجب تحويل الـ Class السابق إلى Dll File ثم وضعه بجانب الملف التنفيذي للمشروع , وأيضا إضافته ضمن الـ References في مشروع الـ Client وحتى نستطيع عمل الـ Casting على الـ Object القادم من الـ Sever ...

أولا : إنشاء الـ Remotting Server :

سيحتوي برنامج الـ Server على الأمور التالية:

04_05_06_10_22_30_1146763350Server_Table.JPG

سنقوم الآن بإنشاء وتسجيل TCP Remote Channel ثم إنشاء الـ Server Object ويتم ذلك كما يلي:

C#:
TcpChannel chan = new TcpChannel(6600);
ChannelServices.RegisterChannel(chan);
RemotingConfiguration.RegisterWellKnownServiceType(Type.GetType("ScreenCapture, ScreenCapture"), "MyCaptureScreenServer",WellKnownObjectMode.Singleton);

VB.NET
Dim chan As TcpChannel = New TcpChannel(6600)
ChannelServices.RegisterChannel(chan)
RemotingConfiguration.RegisterWellKnownServiceType(Type.GetType("ScreenCapture, ScreenCapture"), "MyCaptureScreenServer",WellKnownObjectMode.Singleton)

قمنا بتسمية الـ Server Object بـ MyCaptureScreenServer و طبيعة الـ Instance سيكون Singleton وهذا يعني استخدام نفس الـ Instance Object لكل الـ Clients و في حالة إذا أردنا إنشاء New Instance Object لكل Client Request فيجب استخدام الـ SingleCall وفي حالتنا هذه ينصح باستخدام الأول وحتى لا يزيد الـ Load على الـServer في حالة ربطه على مجموعة كبيرة من الـ Clients إذ أن المعلومات التي يتم بثها إلى الـ Clients هي نفسها ...

ولربط الـ WebCamCapture Class في الـ Picturebox نضع الكود التالي في حدث ImageCaptured الخاص بالـ WebCamCapture Class وكما يلي:

C#:
private void webCamCapture1_ImageCaptured(object source, WebCam_Capture.WebcamEventArgs e)
{
pictureBox1.Image = e.WebCamImage;
}
 
VB.NET:
Private Sub webCamCapture1_ImageCaptured(ByVal source As Object, ByVal e As WebCam_Capture.WebcamEventArgs)
   pictureBox1.Image = e.WebCamImage
End Sub

والآن نستطيع تشغيل الكاميرا عند الضغط على الـ Start Button الموجود في الـ main Menu ونضع في الحدث الخاص بها كود التشغيل ونمرر له الـ Period Time لكل عملية التقاط وهو مثلا 1 Milliseconds ويتم ذلك كما يلي:

C#:
this.webCamCapture1.TimeToCapture_milliseconds = 1;
this.webCamCapture1.Start(0);

VB.NET:
Me.webCamCapture1.TimeToCapture_milliseconds = 1
Me.webCamCapture1.Start(0)

ثانيا : إنشاء الـ Remotting Client :

ويحتوي أيضا على الأمور التالية:

04_05_06_10_23_34_1146763414Client_Table.JPG

وسنقوم بتعريف المتغيرات والـ Objects التالية في الـ Global Declaration للبرنامج:

C#:
ScreenCapture obj;
TcpChannel chan;
string URI;

VB.NET:
Dim obj As ScreenCapture
Dim chan As TcpChannel
Dim URI As String

سنستخدم الـScreenCapture Object لعمل الـ Casting على الـ Incoming Remote Instance Object , وسنستخدم الـ TcpChannel Object لإنشاء الـ Remotting Channel وسنضع في الـ URI String Variable الـ URI الخاص بالـ Server Object والذي تم تعريفه في الـ Server .

ثم سنقوم بوضع التعريفات الأساسية للـ TCP Channel والـ Remote Object في الـConstructer الخاص بالمشروع وكما يلي:

C#:
public Form1()
{

URI = "Tcp://"+textBox1.Text+":6600/MyCaptureScreenServer";
chan = new TcpChannel();
ChannelServices.RegisterChannel(chan);
obj = (ScreenCapture)Activator.GetObject(typeof(ScreenCapture), URI);
}

VB.NET:
URI = "Tcp://" & textBox1.Text & ":6600/MyCaptureScreenServer"
chan = New TcpChannel()
ChannelServices.RegisterChannel(chan)
obj = CType(Activator.GetObject(GetType(ScreenCapture), URI), ScreenCapture)

حيث سيتم تمرير الـ Remote IP أو الـ DNS الخاص بالـ Server من الـ TextBox ويتبعه رقم الـ Port والـ Remote Object الذي تم تعريفه في الـ Client...

ولجلب الصورة سنضع الكود التالي في Timer حيث يجلب الصورة من الـ Server كل فترة محددة:

C#:
private void timer1_Tick(object sender, System.EventArgs e)
{
try
{
URI = "Tcp://"+textBox1.Text+":6600/MyCaptureScreenServer";
byte[] buffer = obj.GetDesktopBitmapBytes();
MemoryStream ms = new MemoryStream(buffer);
pictureBox1.Image = Image.FromStream(ms);
}
catch(Exception ex){timer1.Enabled=false; MessageBox.Show(ex.Message);}
}

VB.NET:
Private Sub timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs)
   Try
       URI = "Tcp://" & textBox1.Text & ":6600/MyCaptureScreenServer"
       Dim buffer As Byte() = obj.GetDesktopBitmapBytes()
       Dim ms As MemoryStream = New MemoryStream(buffer)
       pictureBox1.Image = Image.FromStream(ms)
   Catch ex As Exception
       timer1.Enabled = False
       MessageBox.Show(ex.Message)
   End Try
End Sub

ولتحويل قناة الاتصال إلى Http Channel فقط قم بتغيير الـ TcpChannel إلى HttpChannel وعندها ستتمكن من مشاهدة الـ Remote Methods عبر الـ Internet Browser ولمشاهدتها نضيف الـ WSDL – Services Definition Language Query التالي إلى الـ URI الخاص بالـ Remote Object:

http://10.0.0.10:6600/MyCaptureScreenServer?wsdl

وستظهر لنا الـ Remote Interface Class بهيئة XML لاحظ الشكل التالي:

04_05_06_10_24_30_1146763470xml.JPG

وتستطيع الاستفادة من التركيب السابق للـ Class في حالة لم تتمكن من الحصول على الـ Dll File الخاص بالـ Remote Class , حيث تستطيع تحويل الـ XML السابق إلى ملف Dll لوضعه مع الـ References في برنامج الـ Client ويتم ذلك باستخدام الـMetadata Namespace ومنها الـ w3cxsd2001 Standard حيث يوضع الجزء الأول الخاص بالـ XML Namespace في الـ Serializable Attribute وكما يلي كمثال:

C#:
using System;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Metadata;
using System.Runtime.Remoting.Metadata.W3cXsd2001;

[Serializable,SoapType([email protected]"http://http://schemas.microsoft.com/clr/nsassem/ScreenCapture/ScreenCapture%2C%20Version%3D1.0.2314.30913%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3Dnull")]
public class ScreenCapture : System.MarshalByRefObject
{// Your Methods with Return Values Only}

VB.NET:
Imports System
Imports System.Runtime.Remoting.Messaging
Imports System.Runtime.Remoting.Metadata
Imports System.Runtime.Remoting.Metadata.W3cXsd2001

<Serializable(), SoapTypeAttribute(XmlNamespace:="http://http://schemas.microsoft.com/clr/nsassem/ScreenCapture/ScreenCapture%2C%20Version%3D1.0.2314.30913%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3Dnull"), Serializable(), SoapTypeAttribute(XmlNamespace:="http://http://schemas.microsoft.com/clr/nsassem/ScreenCapture/ScreenCapture%2C%20Version%3D1.0.2314.30913%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3Dnull")> _
Public Class ScreenCapture : Inherits System.MarshalByRefObject
‘Your Methods with Return Values Only
End Class

وللاختيار بين الـ TCP أو الـ HTTP Channel فيفضل دائما في حالة كان الـ Remote Object موجود على جهاز تتصل معه عبر الإنترنت استخدام الـ HTTP Channel بسبب محدودية سرعة الاتصال بالإضافة إلى كونه يتوافق مع أي نظام سواء Windows أو غيره لكن يبقى آداء وسرعة الـ TCP Channel أفضل فقط في الـ Local Network ...

وهكذا بينا كيفية استخدام الـ Remotting في الدوت نيت وطبقنا عملية إنشاء Distributed eLearning System , وبتأكيد تستطيع الآن إضافة ميزة نقل الصوت إلى جانب نقل صورة الشاشة والكاميرا الخاصة بالمحاضر (لمزيد من المعلومات ارجع إلى الفصل الخاص بالـVOIP) , وسنبين في الجزء التالي من هذا الفصل كيفية إنشاء برنامج Remote Desktop Application مع خاصية التحكم (والذي سيتم الحديث عنه في النسخة الورقية من الكتاب) ...

لتحميل الدرس والأمثلة انظر المرفقات:

Remotting__Lesson.zip

تم تعديل بواسطه fmo_82
1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

بعد ملاحظة وجود اعضاء يسئلون عن طرق ربط برنامجين الفيديو والفويس كونفيرانس , فكرت بربطها مع بعضها ولكي يسهل فهمها بشكل اكبر وهذا هو البرنامج في المرفقات

09_05_06_06_53_59_1147182839Peer_Conference_System.JPG

اذا واجهتك اي صعوبة في فهم الكود او كان لديك اقتراح في تطويره لا تتردد في وضع اقتراحك

Peer_Conference_System.zip

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

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

اشكر جزيل الشكر لاستاذنا الفاضل فادي وكل العامليين في هذه المنتدى

كوني جديد في عالم دوت نت وتعلمت اساسيات هذه اللغة في المعهد والى الان

ولكن حبيت ادخل في مجال برمجة الشبكات بتقنية دوت نت

عندي طلب بسيط من استاذنا فادي

اولا : عندي جهاز واحد هل بامكاني تطبيق الدروس وكيف اقوم باعداد الجهاز؟

ثانيا : اذا كان لا بد من جهازين مرتبط بالشبكة كمان كيف اقوم باعدادهم ؟ خطوة خطوة كوني مبتدئ *-)

ولكم مني جزيل الشكر

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

اهلا بك اخي

بتأكيد تستطيع تجربة جميع الأمثلة الموجودة هنا على نفس الجهاز فقط قم بوضع 127.0.0.1 أو كلمة localhost بدل العنوان عند إجراء عملية الإتصال ...

في حالة كان لديك جهاز واحد فقط وتريد تجربة الأمثلة وكأنك تعمل على جهازين أو اكثر انصحك باستخدام برنامج الـ VMware Workstation تستطيع الحصول على نسخة الـ Demo منه من موقع الشركة

http://www.vmware.com

اما طريقة الإعداد فرجع إلى منتدى الشبكات وقم بالبحث عن ما تريد

بتوفيق

تم تعديل بواسطه fmo_82
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

جاري البحث

وجزاك الله خيرا

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

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

اخي فادي قبل قراءتي لكتابك قررت ان اتعلم اساسيات الشبكات

وبحثت عن دروس اساسيات برمجة الشبكات بدوت نت

فوجدتها في قسم VB.NET

في اثناء تطبيقي لدروس واجهني مشكلة ولم اعرف الحل

ارجو منك الاطلاع على الملف المرفق

ولك مني جزيل الشكر

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

اخي فادي قبل قراءتي لكتابك قررت ان اتعلم اساسيات الشبكات

وبحثت عن دروس اساسيات برمجة الشبكات بدوت نت

فوجدتها في قسم VB.NET

في اثناء تطبيقي لدروس واجهني مشكلة ولم اعرف الحل

ارجو منك الاطلاع على الملف المرفق

ولك مني جزيل الشكر

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

لا يوجد مشكلة لديك البرنامج عمل لدي بشكل صحيح اعتقد ان سبب المشكلة من الـ Encoding.Defaultواعتقد السبب من نظام التشغيل بالواجهة العربية والذي تعمل عليه

جرب تغيرها إلى

Me.TextBox1.Text = Encoding.ASCII.GetString(data)

أو إلى

Me.TextBox1.Text = Encoding.Unicode.GetString(data)

إذا اردت دعم اللغة العربية

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

مشكور تعبتك معايا :)

نعم اعمل على واجهة عربية

حاولت اغير في الكود كما قلت ولكن نفس المشكلة !

حاولت اغير في اعدادت الاقليمية واللغات كمان ما عمل معايا !

حاولت اغير من textbox الى messagebox واشتغل لماذا؟؟

انظر الصورة في المرفق

post-44960-1147953592_thumb.jpg

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

يعطيك العافية اخي

دروسك كتير رائعة وشيقة

وانا بصراحة عضو جديد في الفريق العربي للبرمجة

واللي خلاني اسجل متابعة دروسك

بس انا ما بعرف اشتغل على لغة السي شارب

فكنت بتمنى لو دروسك على السي

او السي بلاس بلاس

او حتى الجافا

لاني على الاقل بفهم فيهم شوي

بس اكتر شي بفضل السي

المهم اخي

انا بدي تساعدني في عمل برنامج

Remotting and Client/Server Concept

اقدر من خلالServer اطلع على الملفات الموجودة عندClient

والعكس طبعا

بس ياريت يكون على السي بلاس بلاس او الجافا

علشان افهم شو بتعمل

واكيد راح تستخدم sockets

في البرنامج

وأنا مابعرف أستخدمها أو ما بعرف دوالها

المهم مابعرف عنها شي

بلييييييييييييييييييز ممكن تساعدني

لأني مو عارفة كيف ومن وين أبدأ

وبكون شاكرة لحضرتك كتير

تحياتي

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

اهلا بك اخي الكريم , فيما يتعلق بنقل الملفات فيمكن ذلك باستخدام الـ FileStream حيث يحول الملف إلى Stream عندها يمكن نقله عبر الشبكة يمكنك الرجوع إلى الـ Streaming Chapter4 في الكتاب , بلإضافة انك يمكنك الإستفادة من الـ FTP Protocol , لنقل الملفات والمشاركة بها ارجع إلى الفصل الخاص بالـ FTP Programming , ويمكنك ايضا الإستفادة من الـ HTTP Classes لرفع ملف أو تحميل ملف وهو مشروح بالفصل الخاص بالـ HTTP Programming والكثير الكثير من الطرق ...

في المرفقات مثال جيد يبين كيفية المشاركة ونقل الملفات ,

من المصدر http://www.csharphelp.com/archives2/archive335.html

بتوفيق :)

C__Remotting_Files.rar

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

أنا فضيتك لك يا صديقي ، وبدأت بدراسة سلسلة الدروس

والمشكلة أنك سوف تجد أسئلة عن مقالات قديمة

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

شكرا أخي fmo_82

على هالمثال

جاري التحميل....

مشكور

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

اهلا وسهلا بك اخي احمد وتستطيع السؤال عن أي موضوع, واتوقع منك ايضا المشاركة في دروس جديدة تساهم بها ;)

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

جزاك الله خيرا على كل هذا المجهود الجبار

ولكن ممكن طلب:

-كود بسيط يوضح عملية نقل ملف من الزبون الى السيرفر ويكون بسيييييييييط :D

وجزاك الله كل خير ثانيه على مجهودك العظيم

:D :D

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

ممكن أرد يا أستاذ

ايه المشكلة لو قرأت الملف وحولتة إلى بايت ثم أرسلتة كأنك ترسل صورة

وإذا كان حجم الملف كبير ، يمكنك تقسية إلى مجموعة أجزاء ، وترسلهم الواحد تلو الآخر بعد الإنتظار الرد من السيرفر أنه تم إستلام الجزء السابق

ننتظر رد الأستاذ

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

نعم اخي احمد فهذه طريقة جيدة لكن لست مضطر إلى تجزئة الملف فيما إذا استخدمت الـ Stream Library ومنها الـ Binary Reader والـ Writer ويمكن أيضا إرسال اسم الملف مع محتويات الملف كـ Serialization Object ثم تخزينه على الجهاز بنفس الأسم الذي ارسل عليه وهذا مثال من كتاب احترف برمجة الشبكات النسخة الورقية :

برنامج الإرسال:

FileStream fs = new FileStream(textBox1.Text,FileMode.Open);
byte[] buffer = new byte[fs.Length];
int len = (int)fs.Length;
fs.Read(buffer,0,len);
fs.Close();

BinaryFormatter br = new BinaryFormatter ();
TcpClient myclient = new TcpClient (text_IP.Text,7000);
NetworkStream myns = myclient.GetStream ();
br.Serialize (myns,FileName);

BinaryWriter mysw = new BinaryWriter (myns);
mysw.Write(buffer);
mysw.Close ();
myns.Close ();
myclient.Close ();

برنامج الإستقبال:

NetworkStream myns;
TcpListener mytcpl;
Socket mysocket;
Thread myth;
BinaryReader bb;

void File_Receiver()
{
mytcpl = new TcpListener (7000);
mytcpl.Start ();
mysocket = mytcpl.AcceptSocket ();
myns = new NetworkStream (mysocket);
BinaryFormatter br = new BinaryFormatter ();
object op;

op= br.Deserialize (myns); // Deserialize the Object from Stream


bb = new BinaryReader (myns);
byte[] buffer = bb.ReadBytes(5000000);

FileStream fss = new FileStream(@textBox1.Text + (string) op, FileMode.CreateNew, FileAccess.Write);
fss.Write(buffer,0,buffer.Length);
fss.Close();
mytcpl.Stop();
listBox1.Items.Add ("Successfully Saved to: " + textBox1.Text + (string) op);

if (mysocket.Connected ==true)
{
while (true)
{
File_Receiver();
}
}
}

المثال في المرفقات

File_Transfer.zip

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

شكراااااااااااااااااااااااااااااااااااجزيلا يا د:/ فادى دكتور فعلا

وجزاك الله خيرا

وشكرا للاخ الكريم احمد العوضى على الرد وفعلا كنت بدات فى تنفيذه بطريقة الصوره ولكن واجهتنى بعض المشاكل

حتى جاء رد الدكتور فادى

وشكرااااااااااااااااااااااااااااا جزيلا مره اخرى

:D :D

(ويؤثرون على انفسهم ولو كان بهم خصاصه)

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

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

اخي الكريم فادي بارك الله فيك وجزاك الله خير الجزاء على هذه السلسلة الرائعة وانا لم استطع ان اتابع من البداية لاني جديد في اللغة ومتاخر بعض قليلا ولكن بداءت قراءة كتابك الرابع وانا الان في الفصل الرابع فارجو ان تقبلوني مشاركا جديد في هذه السلسلة الرائعة، واليك سوالي الاول واني لم افهم فكرة الاتصال الغير متزامن حيث لماذا كلما تكتب جملة او ايعاز رئيسي مثلا الدالة (BeginAccept) تقوم باستخدام دالة من نوع AsyncCallback وما فائدة ال callback حيث دائما تنهي الايعاز الرئيسي بكلمة End واسم الدالة مثلا هنا تكتب EndAccept فما الفكرة هنا (اللمشكلة موجودة في صفحة 58 من النسخة الالكترونية الاصدار الاول).

عذرا للاطالة وجزاكم الله خيرا

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

اهلا بكم اخي أبو حفص ولأخ قبل الاول

فيما يتعلق في البرمجة الغير متزامنة وإذا نظرت إلى الشكل التالي:

205002690.jpg

فإنك تلاحظ بقاء الـ Server بوضعية الإنتظار إذ أنه وفي كل عملية طلب للـ Request ما يتم إنهائة باستخدام الـ Endxxx Method وتستدعى هذه الـMethod باستخدام الـ Delegate المخصص لإجراء عملية الإتصال الغير متزامن وهي AsyncCallback وتشبه هذه العملية إلى حد كبير عملية الدخول المباشر إلى المعالجة إذ لا تنتظر إنهاء الـ Server لعملية المعالجة الحالية في حالة ورود طلب جديد وهكذا يسلم أي طلب جديد إلى الـ Endxxx Method لإنهائه وإبقاء حالة الـ Server بوضع الإنتظار ...

ارجو أن تكون الصورة قد وضحت ووفقك الله اخي الكريم

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

بارك الله فيك اخي الكريم وجزاك خير الجزاء ورضي عنك وجعل هذا العلم في ميزان حسناتك، نعم توضحت الفكرة واصبحت مفهومة والحمد لله، سوال اخر اخي الفاضل عندما قمت بتنزيل الملف المكبوس الاصدار الاول مع الامثلة وقمت بعد ذلك بفتح الكبس يضهر لي بعض الاخطاء في فتح الكبس فهل هنالك ملفات ناقصة في الملف المكبوس او يجب استخدام اصدار اخر من ال winrar او غير ذلك رضي الله عنك وجزاك خير الجزاء

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

اهلا بك اخي ابو حفص , على اي حال قم بتثبيت الـ Version 2 من الكتاب من الرابط

http://www.arabteam2000.com/BookLib/show.asp?Id=1109

في المرفقات برنامج الؤتمرات الخاص بلإصدار الثاني مع بعض التعديلات إذا احب احد إقتراح إضافة امور جديدة عليه فيمكنه ذلك:

Multicast Conference Systems

Multicast_Conference_Systems.zip

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

بوركت اخي الحبيب، ما شاء الله ردود سريعة ومتابعة رائعة رضي الله عنك وجزاك خير الجزاء طبعا اخ فادي نحن ازعجناك بكثرة الاسئلة ولكن نحن اخوتك فارجو ان تصبر معنا وشكرا اخي الحبيب.

لي رجعة بعد ان اقراء شوية

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

اخي الفاضل fmo انت قلت

إذا احب احد إقتراح إضافة امور جديدة عليه فيمكنه ذلك:

فانا اتمنى ان تقوم بتطوير البرنامج باضافة امكانية تحكم حاسبة الاستاذ بحاسبات الطلاب حيث يقوم الاستاذ بتحريك الماوس الخاص بالطالب والكتابة بالكيبورد الخاص بالطالب وهكذا يكون البرنامج رائع جدا جدا، واذا اعجبتك الفكرة فسنكون نحن معك ونتابع معك اولا باول وجزاك الله خير

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

اسلام عليكم بالفعل اخي فالفكرة جميلة وقد قمت بتطبيقها في الكتاب لكن بمثال اخر على اي حال إذا احب الأعضاء وضع الدرس المتعلق بالتحكم عن بعد هنا فلهم ذلك بإذن الله , لكن وجب على الجميع التفاعل لتطوير المهارات

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

من فضلك سجل دخول لتتمكن من التعليق

ستتمكن من اضافه تعليقات بعد التسجيل



سجل دخولك الان

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .