تقييم الموضوع :
  • 1 أصوات - بمعدل 5
  • 1
  • 2
  • 3
  • 4
  • 5
[سلسلة التعامل مع الويب] - ارسال الطلبات HttpWebRequset
#1
السلام عليكم ورحمة الله وبركاته



نرحب بكم ساداتي الكرام في هذا الشهر الفضيل في اول موضوع من سلسلة [التعامل مع الويب]

تتكون السلسة من 3 مقالات مختلفة تتعلق بالتعامل مع الويب او صفحات الويب

اتت فكرة الموضوع منذ فترة في بالي ، حيث لا يوجد مصدر عربي واحد

يتكلم عن التعامل مع الويب ، فهذا هو الموضوع الاول والحصري

للتعامل مع الطلبات والويب
، في الحقيقة كان من المفترض ان

تكون المقالة على لغتي VB + سي شارب ، ولكن

احس ان السي شارب مظلومة شوي فقررت اجعل الدروس حصريا لها

بالاضافة ان المقالة طويلة نوعا ما فوجود اكواد كثيرة يربك القارئ ويربكني ايضاCool

إن شاء الله تنفعكم المقالة والمقالات القادمة

ونبدأ معكم اخواني الاعزاء مقالتنا الجميلة.Wink





--
--
--




صفر :-   أجزاء المقالة



1- تعريف طلبات الويب (Web requset)
2- بروتوكولات طلبات الويب
3- خصائص وطرق كائن ارسال الطلبات
4- جلب صيغة الطلب
5- ارسال الطلب
6.1- استخدام Cookies Container مع الطلبات
6.2- طريقة استخدام الطلبات لتسجيل الدخول في المنتدى
7- طريقة استخدام الطلبات لرفع البيانات لمراكز الرفع
8- التعامل مع سيرفر الFTP باستخدام كائن ارسال طلبات FTP
9- الخاتمة





--
--
--




اولا :-  تعريف الطلب


الطلب هو بيانات ترسلها لخادم الويب(Server) لكي يقوم بعمل ما.
كل طلب يتم ارساله للسيرفر ، يتم استقبال رد (Response) عليه

فاتسجيل الدخول للمنتديات مثلا ، يتم بالضغط على زر Log in في المنتدى
عندما يتم الضغط على الزر ، يرسل المتصفح طلبا يحتوي على بيانات العضوية

يتلقى الخادم الطلب ويعالجه (يبحث في قاعدة البيانات) ويرسل ردا يحتوي على بيانات
يترجم المتصفح الرد ويعرض لك المحتوى المترجم .



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



--
--
--




ثانيا :-  بروتوكولات الطلبات


يوجد العديد من البروتوكلات المستخدمة في ارسال الطلبات
ابرزها :-

-
1- Post : وهو البروتوكول الاكثر شيوعا وسنتخدمه كثيرا ،
هذا البروتوكول يستخدم لـ إرسال معلومات من المستخدم الزبون (من form في صفحة html مثلا) للخادم ، مثلا
انشاء موضوع في المنتدى يتطلب ارسال بيانات (العنوان ، نص الموضوع ، الكلمات الدلالية ....الخ)
او تسجيل الدخول للمنتدى ، او البحث -- كل هذا يتم عبر Post Requset


2- Get : وهو بروتوكول يستخدم لعرض طلبك (صورة-ملف-صفحة Html ,وغيرها)
مثلا لو اريد ان اعرض صفحة قوقل الرئيسية ، اقوم بإرسال طلب Get ، ثم يرسل لي الخادم
ردا (Response) يحتوي على اكواد Html للصفحة



3- Head : هو برتوكول مشابه كثيرا لـ Get ،
الـ Get يقوم بجلب طلبك(صورة-صفحة-ملف) مع شيئ اسمه Response header
لكن الـHead يقوم بجلب Response header فقط دون جلب المحتوى - يعني لو اردت
الإستعلام عن مساحة ملف فقط استخدم Head ولا يجوز Get ، لأن Get راح تجلب لي المحتوى ، يعني بتعطينا الBytes للملف
>الـ Response header هي معلومات عن الرد يرسلها لك السيرفر عند تلقي الطلب<

سنتعرف على الـResponse Header و Request Header لاحقا


4- Put : بروتوكول يستخدم لرفع ملف
-



هذي البروتوكولات المشهورة ولاحاجة لذكر غيرها
للمزيد عن هذه البروتولات قم بزيارة الرابط التالي : هنا



--
--
--




ثالثا :-  كائن ارسال الطلبات


الفئة السحرية التي تمكننا من ارسال الطلبات اسمها HttpWebRequset ضمن مجال الاسماء System.Net

والفئة التي تمكننا من اسقبال الردود اسمها HttpWebResponse ضمن مجال الاسماء System.Net

هاتان الفئتان كلاهما abstract

اي لايمكنك عمل نسخة منهما

فلتعريفها نكتب التالي :


PHP كود :
HttpWebRequest rq = (HttpWebRequest)WebRequest.Create("http://www.google.com"); 


قمنا بتعريف كائن وقما بإنشاء طلب.

لاتنسى اضافة مجال الاسماء في اعلى المحرر :


PHP كود :
using System.Net




--

لن نحاول ان نرسل طلبا الان ، في هذا الجزء من المقالة سنقوم بـ شرح بعض الدوال والخصائص المهمة

--



خصائص كائن ارسال الطلب (HttpWebRequset)


1- خاصية Address : تعطيك رابط الطلب

2- خاصية AllowAutoRedirect : السماح للسيرفر بتحويل رابط الطلب الى رابط اخر

3- خاصية ContentLength : سحب او اعطاء طول بيانات الطلب

4- خاصية ContentType : سحب او اعطاء نوع الطلب - مهم جدا لطلبات بروتوكول POST

5- خاصية CookieContainer : سحب او اعطاء حاوية الكوكيز - سنتعرف لها لاحقا

6- خاصية Credentials : سحب او اعطاء بيانات الوصول مثلا(USERNAME او PASSWORD) - كسيرفرات FTP على سبيل المثال

7- خاصية KeepAlive : سحب او اعطاء قيمة تعبر عن استمرارية الاتصال مع السيرفر - تستعمل عند رفع الملفات عادا كي لاينقطع الاتصال

8- خاصية Method : من اهم الخواص - تستعمل لإختيار البروتوكول المستعمل للطلب (POST, GET , ...etc)

9-خاصية Timeout : الوقت المحدد لإلغاء الطلب في حالة عدم استجابة السيرفر اوعدم وصول الرد في الوقت المحدد

10- خاصية UserAgent : وكيل المستخدم - هو نص يعبر عن المتصفح المستخدم في الطلب (او المنصة الحالية) عادا
تظهر الفائدة الكبرى لهذه الخاصية عندما يكون تطبيقك لعدة منصات فمثلا ، اجهزة الجوال تعرض صفحات الويب بشكل اخر عن الكمبيوتر
جرب تدخل الyoutube من جوالك وشوف ، هنا تم استعمال UserAgent خاص عند طلب فتح صفحة اليوتيوب لكي تعرض بشكل الجوال ، لا بشكل الكمبيوتر المعتاد



--


إجرائات ودوال كائن ارسال الطلب (HttpWebRequset)


1- الاجراء Abort : الغاء الطلب

2- دالة GetRequestStream : فتح تيار كتابة البيانات للطلب - مهم جدا ، فهنا نكتب بيانات الطلب ، كبيانات العضوية او بيانات ملف الخ...

3- دالة GetResponse : ارسال الطلب + جلب الرد ، دالة دائما وابدا تستخدم في الطلب حيث ان الطلب لايتم الى باستدعائها



هكذا انتهينا من الدوال والخصائص المهمة




--
--
--





رابعا :-  جلب صيغة الطلب


نبدأ الان الشغل العملي في هذا الجزء

في البداية ماذا نريد ان نفعل ؟!!

كبداية نريد ان نقوم بإرسال طلب لتحويل كود bb to html عبر موقع وعرض صفحة النتائج في اداة WebBrowser

الان وقد حددنا الهدف - نقوم بداية بتنزيل اضافة الفايرفوكس live http headers من هنا

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

نقوم بتنزيلها وتركيبها .

اذهب الى الموقع وقم بفتح نافذة الاضافة

صورة :


هذه نافذة الاضافة



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



وقبل ان تضغط تحويل قم بتفعيل القنص

واضغط تحويل ، وفور ظهور صفحة النتائج



قم[/COLOR] بإلغاء القنص

ستكون معلومات الطلب كالتالي :


فسيكون الكود كالتالي

PHP كود :
           Encoding charset Encoding.GetEncoding("iso-8859-1");
 
           string stringData string.Format("bbcode={0}&submit=Convert+BBCode+to+HTML&alt=yes&xhtml=yes""[u]ABO MUSLEM[/u]");
 
           byte[] postData charset.GetBytes(stringData);

 
           HttpWebRequest rq = (HttpWebRequest)WebRequest.Create("http://bbcode-to-html.com");
 
           rq.Method WebRequestMethods.Http.Post;
 
           rq.ContentType "application/x-www-form-urlencoded";
 
           rq.ContentLength postData.Length;
 
           System.IO.Stream wr rq.GetRequestStream();
 
           wr.Write(postData,0,postData.Length);
 
           wr.Close();

 
           HttpWebResponse rs = (HttpWebResponse)rq.GetResponse();

 
           System.IO.StreamReader reader = new System.IO.StreamReader(rs.GetResponseStream(), charset);

 
           webBrowser1.DocumentText reader.ReadToEnd(); 



--
--
--





خامسا :-  ارسال الطلب



شرح الاكواد السابقة :-


في السطر الاول قمنا بتعريف ترميز وهذا امر ضروري جدا لبيانات الطلب - حيث ان الطلب لايتم اذا كان الترميز خاطئ
<جلب الترميز يتم بعدة طرق منها اليدوية ومنها الالية>
الطربقة الالية هي باستعمال طلب اخر في دالة كالتالي
PHP كود :
       public Encoding getEncoding(string url)
 
       {
 
           HttpWebRequest rq = (HttpWebRequest)WebRequest.Create(url);
 
           HttpWebResponse rs = (HttpWebResponse)rq.GetResponse();
 
           return Encoding.GetEncoding(rs.CharacterSet);
 
       

واستبدال السطر الاول برابط الموقع
PHP كود :
Encoding charset getEncoding("http://bbcode-to-html.com"); 


الطريقة اليدوية :- موجود في سورس الصفحة نوع الترميز المستخدم ضمن الTag Head


--

السطر الثاني : بيانات الطلب ونحصل عليه في الاضافة (الصورة تحت)


يتم الفصل بين بارمترات البيانات بـ &

فنقوم باستبدال المتغيرات والحفاظ على الثوابت
PHP كود :
string.Format("bbcode={0}&submit=Convert+BBCode+to+HTML&alt=yes&xhtml=yes""[u]ABO MUSLEM[/u]"

الكود في الاداة
كود :
bbcode=[color=#FF0000]%5BB%5Dmohammed%5B%2FB%5D[/color][color=#40E0D0]&[/color]submit=Convert+BBCode+to+HTML[color=#40E0D0]&[/color]alt=yes[color=#40E0D0]&[/color]xhtml=yes

انا قمت بحذف %5BB%5Dmohammed%5B%2FB%5D

فهذا يعبر عن النص الذي نريد ان نحوله

ووضعت هذا بداله لكي يتم تحويله

PHP كود :
"[u]ABO MUSLEM[/u]" 

--
السطر الثالث
PHP كود :
byte[] postData charset.GetBytes(stringData); 

تعريف متغير من نوع مصفوفة byte

ويتم تحويل نص البيانات الى بايتات

لأن عشان نرسل طلب لازم تكون البيانات بصيغة البايت


--
السطر الرابع
PHP كود :
HttpWebRequest rq = (HttpWebRequest)WebRequest.Create("http://bbcode-to-html.com"); 

إنشاء طلب

وقمنا بوضع رابط الطلب

كما هو موضح رابط الطلب يوجد في اعلى الهيدر للطلب




--

السطر الخامس

PHP كود :
rq.Method WebRequestMethods.Http.Post

البروتوكول المستخدم لإرسال الطلب وهو موجود في الاضافة (الصورة فوق)


--

السطر السادس
PHP كود :
rq.ContentType "application/x-www-form-urlencoded"

كود مهم جدا - ولا يمكن ارسال طلب POST اذا لم يكن موجود

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


--

السطر السابع
PHP كود :
rq.ContentLength postData.Length

طول بيانات الطلب = طول مصفوفة البيانات

كود مهم جدا للإرسال POST


--

الكود الثامن
PHP كود :
System.IO.Stream wr rq.GetRequestStream(); 

جلب تيار الكتابة لكي نكتب بيانات الطلب

--

الكود التاسع
PHP كود :
wr.Write(postData,0,postData.Length); 

نكتب بياناتنا

--

الكود العاشر
PHP كود :
HttpWebResponse rs = (HttpWebResponse)rq.GetResponse(); 

ارسال الطلب + جلب الرد

--

الكود الحادي عشر
PHP كود :
System.IO.StreamReader reader = new System.IO.StreamReader(rs.GetResponseStream(), charset); 

جلب تيار القراءة لكي نقرأ الرد بواسطة دالة مهمة في فئة HttpWebRespons
وهي GetResponseStream



--

الكود الثاني عشر وهو الحاسم
PHP كود :
webBrowser1.DocumentText reader.ReadToEnd(); 

دالةReadToEnd تجلب لك محتوى الرد

ونقوم بعرض المحتوى في اداة الwebbrowser


النتيجة :



تم تحويل

PHP كود :
[u]ABO MUSLEM[/u
في كود :
PHP كود :
string stringData string.Format("bbcode={0}&submit=Convert+BBCode+to+HTML&alt=yes&xhtml=yes""[u]ABO MUSLEM[/u]"); 


الى صيغة الhtml

PHP كود :
<p><span style="text-decoration: underline;">ABO MUSLEM</span></p

وذلك عبر ارسال طلب لموقع http://bbcode-to-html.com
-
انتهينا من هذا الجزء (ارسال الطلب)


>لاتقلق اذا لم تفهم ففي جعبتنا العديد من التطبيقات القادمة<




--
--
--




{يتبع الجزء السادس} >>>
الرد }}}
#2

[b]سادسا :- استخدام Cookies Container مع الطلبات



ماهو Cookies Container ؟؟

-هو فئة تخزن الكوكيز لكي نستعمله في طلب اخر

ابسط مثال هو انشاء موضوع جديد في المنتدى

يتطلب انشاء موضوع الى تسجيل الدخول في المنتدى

وتسجيل الدخول يتطلب ارسال طلب من برنامجنا مثلا

فالنفرض انه سوينا طلب تسجيل الدخول وتم الرد علينا بنجاح تسجيل الدخول

ثم حاولنا ان نكتب طلبا اخر لنضع موضوعا وقمنا بارسال الطلب .

الرد سيأتيك مباشرة في الصميم يقولك (إنشاء الموضوع فشل والسبب لم يتم تسجيل الدخول)

رغم أننا ارسلنا طلبا مسبقا لتسجيل الدخول ونجح ،

لكن كما نعلم ان بيانات تسجيل الدخول في جميع المواقع تخزن في الكوكيز والطلب يمكنه حفظ الكوكيز

في كائنه فقط - يعني كائن ارسال طلب تسجيل الدخول لاإرتباط له بكائن ارسال طلب انشاء الموضوع

فالذي سنفعله هو نسخ الكوكيز المرجع من الرد على طلب تسجيل الدخول الى كائن ارسال طلب إنشاء الموضوع

-

مثال على نسخ الكوكيز

PHP كود :
CookieContainer cookies = new CookieContainer();
          
            
HttpWebRequest LoginRequset = (HttpWebRequest)WebRequest.Create("http://vb4arb.com/vb/login.php");
             
LoginRequset.CookieContainer _cookies//مهم
            //...
            
HttpWebResponse LoginResponse = (HttpWebResponse)LoginRequset.GetResponse();
            
cookies.Add(LoginResponse.Cookies);
            
//... 

كما ترون اخواني كوكيز الرد سيتم حفظهما في الكائن cookies

لاحظ هذا الكود
PHP كود :
cookies.Add(LoginResponse.Cookies); 

[COLOR="#8B4513"]هو الاساس للحصول على كوكيز تسجل الدخول

فعندما ترسل طلب يحتوي على بيانات عضوية صحيح ، يتم الرد عليك بكوكيز الدخول

وهذا الكوكيز صالح لفترة معينة

لكن :- يمكننا العبث في كائن الكوكيز وتغير محتوايته ليظل للأبد ، ولكن هذا مو موضوعنا الان[/COLOR]

-

[COLOR="#8B4513"]الان يمكننا استعمال هذا الكوكيز في القيام بأي عملية في الموقع تحتاج الى تسجيل الدخول ،

كإنشاء موضوع مثلا .

ملاحظة : لن اقوم بصنع طلب لإنشاء موضوع لأن الوضع معقد قليل فهو يحتاج الى تحليل صفحات

واستخراج securityToken اي رمز الامان

هم سووه عشان لااحد يسوي مثلنا ويرسل موضوع من برنامج بواسطة الطلب

لكن يمكن جلبه بالتحليل وهذا عنوان مقالتنا القادمة ان شاء الله[/COLOR]


------


ماذا سنفعل الان ؟؟
[COLOR="#4B0082"]
بدل انشاء موضوع وتعقيد الامر عليكم بما انكم مبتدأين

فقررت ان نقوم بعرض "المتواجدون الان"

كما نعلم ان صفحة (المتواجدون الان) ستفتح لك اذا كنت مسجل دخولك

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

وكالعادة منعرضها في اداة WebBrowser رغم انه يمكننا حفظها محتوى الرد كملف او غيره[/COLOR]

----
نبدأ الان - بسم الله

[COLOR="#0000CD"]
1- قم بالذهاب الى صفحة تسجيل الدخول في المنتدى واكتب بياناتك (ولتكن صفحة المنتدى الرئيسية)

2- افتح الاداة Live http header

3- قم بالضغط على زر تسجيل الدخول

4- مباشرة قم بإلغاء القنص بعد ظهور صفحة الترحيب لك

5- نكتب طلبنا بالاعتماد على البيانات الي حصلنا عليها من الاضافة[/COLOR]


صورة :


[COLOR="#800000"]الصورة كما شرحناها سابقا ولكن شرحتها الان لتثبيت المعلومة
-

نريد في البداية أن نحصل على بيانات الطلب

كما نرى ان بيانات الطلب ظاهرة لكن استعمال replay يظهر افضل[/COLOR]





--

الان هذا هذه هي بيانات الطلب :

كود :
vb_login_username=%C7%E1%D4%C7%DF%ED+%E1%E1%E5[color=#FF0000]&[/color]vb_login_password=[color=#FF0000]&[/color]vb_login_password_hint=%DF%E1%E3%C9+%C7%E1%E3%D1%E6%D1[color=#FF0000]&[/color]cookieuser=1[color=#FF0000]&[/color]s=[color=#FF0000]&[/color]securitytoken=guest[color=#FF0000]&[/color]do=login[color=#FF0000]&[/color]vb_login_md5password=4a7d1ed414474e4033ac29ccb8653d9b[color=#FF0000]&[/color]vb_login_md5password_utf=4a7d1ed414474e4033ac29ccb8653d9b

[COLOR="#800000"]
الان نحدد الاشياء الي تتغير بين كل مستخدم واخر

بالطبع اليورزنيم والباسوورد يختلفو بين كل مستخدم واخر

افتح النوت باد وإلصف البيانات

ونحذف قيمة vb_login_username ونضع بدالها : {0}[/COLOR]
كود :
vb_login_username={0}

--
ونحدف قيمة vb_login_md5password + vb_login_md5password_utf ونضع بدالهما {1}

كود :
vb_login_md5password={1}[color=#FF0000]&[/color]vb_login_md5password_utf={1}

--
[COLOR="#000000"]بقية البارمترات هي ثوابت لاتختلف بين شخص الى اخر
فقط اليوزرنيم والباسوورد يخلتفو من مستخدم لإخر

قبل كل شيئ ، يعرف ان منتديات vbluttien تتعامل مع الباسوردات بصيغة MD5
وقد لاحظنا وجود MD5 في بارمتار الباسورد : vb_login_md5password

هذا يعني انه لايمكننا كتابة باسوورد بهذي الطريقة 89139 وإرساله مع الطلب
يعني يجب علينا تحويل الباسوورد الى صيغة MD5

قمت بالبحث في الانترنت ووجدت دالة تقوم بتحويل النص الى صيغة MD5 :[/COLOR]

PHP كود :
public static string MD5(string STR)
        {
            
ASCIIEncoding encoding = new ASCIIEncoding();
            
string str string.Empty;
            
byte[] bytes encoding.GetBytes(STR);
            
byte[] buffer2 = new MD5CryptoServiceProvider().ComputeHash(bytes);
            foreach (
byte num in buffer2)
            {
                
str str num.ToString("x2");
            }
            return 
str;
        } 
[COLOR="#FF0000"]
لاتنسى اضافة مجال الاسماء التالي:[/COLOR]
PHP كود :
using System.Security.Cryptography


نقوم بإضافة متغير عام :
PHP كود :
CookieContainer _cookies = new CookieContainer(); 


الان نقوم بكتابة طلب تسجيل الدخول ويكون كالتالي :

PHP كود :
Encoding charset getEncoding("http://vb4arb.com/vb");


            
string Password MD5("8798797");
            
string stringData string.Format("vb_login_username={0}&vb_login_password=&vb_login_password_hint=%DF%E1%E3%C9+%C7%E1%E3%D1%E6%D1&cookieuser=1&s=&securitytoken=guest&do=login&vb_login_md5password={1}&vb_login_md5password_utf={1}",
                
"شكشوك"Password);
            
byte[] postData charset.GetBytes(stringData);

            
HttpWebRequest LoginRequset = (HttpWebRequest)WebRequest.Create("http://vb4arb.com/vb/login.php?do=login");
            
LoginRequset.ContentType "application/x-www-form-urlencoded";
            
LoginRequset.Method WebRequestMethods.Http.Post;
            
LoginRequset.ContentLength postData.Length;
            
LoginRequset.CookieContainer _cookies;
            
LoginRequset.KeepAlive true;
            
System.IO.Stream wr LoginRequset.GetRequestStream();
            
wr.Write(postData0postData.Length);
            
wr.Close();
            
using (HttpWebResponse LoginResponse = (HttpWebResponse)LoginRequset.GetResponse())
            {
                
_cookies.Add(LoginResponse.Cookies);
            } 


[COLOR="#FF0000"]الاكواد شرحناها سابقا لاحاجة لشرحها


ملاحظة : استخدمت دالة getEncoding الي شرحتها في ردي السابق

ملاحظة 2 : لاحظ اننا استعملنا using ، استعملناها لكي يتم تدمير الكائن LoginResponse فور انتهاء البلوك

لأن يحصل خطا اذا سويت طلبين لنفس الموقع وماقمت بدمير الresponse

ينتهي هذا الكود بحفظ كوكيز العضوية في المتغير العام[/COLOR]
PHP كود :
_cookies.Add(LoginResponse.Cookies); 

--
--

الان نقوم باستخدام الكوكيز لنعرض صفحة[COLOR="#B22222"] "المتواجدون الان" التي تتطلب كوكيز تسجيل الدخول

نقوم بالذهاب الى صفحة المتواجدون الان ونقوم بتشغيل القنص

ثم نضغط refresh في المتصفح ليتم اعادة عرض الصفحة وإعادة الطلب[/COLOR]

صورة :



كما ترى لايوجد [COLOR="#FF0000"]post Data لأن البروتوكول المستخدم هو GET

GET كما شرحناها سابقا تستخدم لطلب عرض صفحة او ملف او.....

فنقوم الان بكتابة طلب عرض الصفحة ويكون الكود هكذا :[/COLOR]


PHP كود :
HttpWebRequest onlineRequset = (HttpWebRequest)WebRequest.Create("http://vb4arb.com/vb/online.php");
            
onlineRequset.Method "GET";
            
onlineRequset.CookieContainer _cookies//مهم
            
HttpWebResponse onlineResponse = (HttpWebResponse)onlineRequset.GetResponse();
            
webBrowser1.DocumentStream onlineResponse.GetResponseStream(); 



يكون الكود كاملا كالتالي :

PHP كود :
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Text;
using System.Windows.Forms;
using System.Security.Cryptography;

namespace 
WindowsFormsApplication1
{
    public 
partial class Form1 Form
    
{
        public 
Form1()
        {
            
InitializeComponent();
        }

        public static 
string MD5(string STR)
        {
            
ASCIIEncoding encoding = new ASCIIEncoding();
            
string str string.Empty;
            
byte[] bytes encoding.GetBytes(STR);
            
byte[] buffer2 = new MD5CryptoServiceProvider().ComputeHash(bytes);
            foreach (
byte num in buffer2)
            {
                
str str num.ToString("x2");
            }
            return 
str;
        }


        public 
Encoding getEncoding(string url)
        {
            
HttpWebRequest rq = (HttpWebRequest)WebRequest.Create(url);
            
HttpWebResponse rs = (HttpWebResponse)rq.GetResponse();
            return 
Encoding.GetEncoding(rs.CharacterSet);
        }



        
CookieContainer _cookies = new CookieContainer();

        private 
void button1_Click(object senderEventArgs e)
        {
            
Encoding charset getEncoding("http://vb4arb.com/vb");


            
string Password MD5("8798797");
            
string stringData string.Format("vb_login_username={0}&vb_login_password=&vb_login_password_hint=%DF%E1%E3%C9+%C7%E1%E3%D1%E6%D1&cookieuser=1&s=&securitytoken=guest&do=login&vb_login_md5password={1}&vb_login_md5password_utf={1}",
                
"شكشوك"Password);
            
byte[] postData charset.GetBytes(stringData);

            
HttpWebRequest LoginRequset = (HttpWebRequest)WebRequest.Create("http://vb4arb.com/vb/login.php?do=login");
            
LoginRequset.ContentType "application/x-www-form-urlencoded";
            
LoginRequset.Method WebRequestMethods.Http.Post;
            
LoginRequset.ContentLength postData.Length;
            
LoginRequset.CookieContainer _cookies//مهم
            
LoginRequset.KeepAlive true;
            
System.IO.Stream wr LoginRequset.GetRequestStream();
            
wr.Write(postData0postData.Length);
            
wr.Close();
            
using (HttpWebResponse LoginResponse = (HttpWebResponse)LoginRequset.GetResponse())
            {
                
_cookies.Add(LoginResponse.Cookies);
            }



            
//GET
            //المتواجدون الان


            
HttpWebRequest onlineRequset = (HttpWebRequest)WebRequest.Create("http://vb4arb.com/vb/online.php");
            
onlineRequset.Method "GET";
            
onlineRequset.CookieContainer _cookies//مهم
            
HttpWebResponse onlineResponse = (HttpWebResponse)onlineRequset.GetResponse();
            
webBrowser1.DocumentStream onlineResponse.GetResponseStream();

        }


    }




شغل البرنامج وستراه يظهر لك "المتواجدون الان"

لولا الكوكيز لما استطعنا الوصول لهذه الصفحة

--
--


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


--
--
--





{يتبع الجزء السابع} >>>

[/b]


الملفات المرفقة
.zip   Online Now.zip (الحجم : 94.33 ك ب / التحميلات : 108)
الرد }}}
تم الشكر بواسطة: السندبااد , أسامة , ابو ليلى , ابو ليلى
#3
[COLOR="#000000"]
[b]سابعا :- رفع الملفات لمراكز الرفع

[COLOR="#800000"]

في هذا الجزء راح نتكلم عن طريقة رفع ملف الى مراكز الرفع

حيث ان بيانات الطلب معقدة وتتطلب طريقة خاصة للتعامل

مارح اشرح كل جملة في هذا الجزء كما كنت افعل سابقا

بسبب ضيق الوقت + اعتقد صرتوا محترفين Big Grin + يجب عليي وضع المقالة القادمة اليوم
[/COLOR]
--

نبدأ ببركة الله


[COLOR="#000080"]كما قلنا نريد أن نرفع ملف الى مركز رفع

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

الامثلة راح تكون على موقعين

الموقع الاول هو Iraqup لرفع الصور

ندخل عليه ونختار صورة .

- وقبل لاترفع ، لاتنسى تشغل قنص الطلبات في أداة Live http header لنتمكن من الحصول على الطلب[/COLOR]

-----

[COLOR="#000000"]بعد الرفع :




كما ترى الPost Data معقدة وليست كابقية الداتا الي تعامنا معاها سابقا

بالاضافة الى وجود -----------------------------176483200027146 ،

وهذا رقم يتغير في كل مرة ترفع فيها وماتقدر تخلي رقم عشوائي

لهذا قمت بعمل جزء خاص يتكلم عن الرفع للمراكز[/COLOR]


--
[COLOR="#8B4513"]
الفئة الذهبية لرفع الملفات للمراكز :[/COLOR]

PHP كود :
public class UploadStationPOST
    
{
        
//Copyright for ALshkiLLah
        /// <summary>
        /// Upload your data to upload stations.
        /// </summary>
        /// <param name="url">Post url</param>
        /// <param name="parameters">Post data parameters</param>
        /// <returns></returns>
        
public static string PostToStations(string PostURLDictionary<stringobjectPostDataParameters)
        {
            
string boundary "---------------------------" DateTime.Now.Ticks.ToString("x");
            
byte[] boundaryBytes System.Text.Encoding.ASCII.GetBytes("\r\n--" boundary "\r\n");

            
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(PostURL);
            
request.ContentType "multipart/form-data; boundary=" boundary;
            
request.Method "POST";
            
request.KeepAlive true;
            
request.Credentials System.Net.CredentialCache.DefaultCredentials;

            if (
PostDataParameters != null && PostDataParameters.Count 0)
            {

                
using (Stream requestStream request.GetRequestStream())
                {

                    foreach (
KeyValuePair<stringobjectpair in PostDataParameters)
                    {
                        
requestStream.Write(boundaryBytes0boundaryBytes.Length);
                        if (
pair.Value is FileDisposition)
                        {
                            
FileDisposition file = (FileDisposition)pair.Value;
                            
string header "Content-Disposition: form-data; name=\"" pair.Key "\"; filename=\"" file.Name "\"\r\nContent-Type: " file.ContentType "\r\n\r\n";
                            
byte[] bytes System.Text.Encoding.UTF8.GetBytes(header);
                            
//كتابة معلومات الملف
                            
requestStream.Write(bytes0bytes.Length);

                            
byte[] buffer = new byte[1]; //تجهيز المصفوفة  
                            
int bytesRead;
                            
// كتابة بايتات الملف
                            
using (FileStream fileStream File.OpenRead(file.FilePath))
                            {
                                while ((
bytesRead fileStream.Read(buffer0buffer.Length)) != 0)
                                {
                                    
requestStream.Write(buffer0bytesRead);
                                }
                                
fileStream.Close();
                            }
                        }
                        else
                        {
                            
//البارمترات الاخرى غير بارمتار فايلس
                            
string data "Content-Disposition: form-data; name=\"" pair.Key "\"\r\n\r\n" pair.Value;
                            
byte[] bytes System.Text.Encoding.UTF8.GetBytes(data);
                            
requestStream.Write(bytes0bytes.Length);
                        }
                    }
                    
byte[] trailer System.Text.Encoding.ASCII.GetBytes("\r\n--" boundary "--\r\n");
                    
requestStream.Write(trailer0trailer.Length);
                    
requestStream.Close();
                }
            }


            
//الرد
            
using (WebResponse response request.GetResponse())
            {
                
using (Stream responseStream response.GetResponseStream())
                {
                    
using (StreamReader reader = new StreamReader(responseStreamEncoding.UTF8))
                        return 
reader.ReadToEnd();
                }
            }
        }


        public class 
FileDisposition
        
{
            public 
string Name getset; }

            public 
string ContentType getset; }

            public 
string FilePath getset; }
        }

    } 

الان لكي نرفع ملف نحتاج لبيانات الطلب مرة اخرى
[COLOR="#FF0000"]
في النهاية الكود الكامل لرفع صورة لموقع iraqUp هو هذا[/COLOR]

PHP كود :
string postURL "http://www.iraqup.com/index2.php";
            
//ResultButton.Enabled = false;
            
string ext System.IO.Path.GetExtension(textBox1.Text).ToLower();
            
ext ext.Remove(0,1);
            if (
ext == "jpg"){ext="jpeg";} //on internet jpg is named jpeg

            
Dictionary<stringobjectpara = new Dictionary<stringobject>();
            
//para



            
para.Add("userfile", new UploadStationPOST.FileDisposition()
            {
                
Name "ali.png",  //اسم الصورة
                
ContentType "image" ext//صيغة الصورة
                
FilePath "c://ali.png" //مكان الصورة
            
});


            
//post
            
_result UploadStationPOST.PostToStations(postURLpara); 

[COLOR="#4B0082"]سيتم حفظ محتوى الرد في المتغير result وهو عبارة عن صفحة الصورة بعد ماانرفعت

البارمترات
Name : اسم الصورة
ContentType : صيغة الصورة
FilePath : مسار الصورة على جهازك[/COLOR]

صورة :



--


سنحاول الان الرفع على موقع اخر

وهو http://www.0zz0.com

ارفع ملف وشوف تنسيق بيانات الطلب





هناك 3 برامترات ، عكس الموقع السابق كان في برامتار واحد بس واسمه [COLOR="#FF0000"]userfile

اما هنا يوجد 3

فسنتظطر الى زيادة القاموس لنتمكن من الرفع له[/COLOR]

PHP كود :
string postURL "http://www.0zz0.com/index.php";
            
//ResultButton.Enabled = false;
            
string ext System.IO.Path.GetExtension(textBox1.Text).ToLower();
            
ext ext.Remove(0,1);
            if (
ext == "jpg"){ext="jpeg";} //on internet jpg is named jpeg

            
Dictionary<stringobjectpara = new Dictionary<stringobject>();
            
//para


            
para.Add("APC_UPLOAD_PROGRESS""83738829");//new para
            
para.Add("upload""ok");//new para
            
para.Add("file2up[]", new UploadStationPOST.FileDisposition()
            {
                
Name "ali.png",  //اسم الصورة
                
ContentType "image" ext//صيغة الصورة
                
FilePath "c://ali.png" //مكان الصورة
            
});


            
//post
            
_result UploadStationPOST.PostToStations(postURLpara); 


لاحظ قمنا بزيادة
PHP كود :
para.Add("APC_UPLOAD_PROGRESS""83738829");//new para
            
para.Add("upload""ok");//new para 
[COLOR="#006400"]
لأن في موقع iraqup كان يوجد Parameter واحد بس !!

اما في موفع العملاق يوجد Parameter ثلاثة[/COLOR]

لاحظ ايضا قمنا بتغير المفتاح الثالث من userfile الى file2up[]





---
---



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



---
---
---


{يتبع الجزء الثامن} >>>

[/COLOR]
[/b]


الملفات المرفقة
.zip   IraqUp.zip (الحجم : 70.93 ك ب / التحميلات : 98)
الرد }}}
تم الشكر بواسطة: السندبااد , أسامة
#4
[b]ثامنا :- التعامل مع FTP من خلال الطلبات


[COLOR="#800000"]التعامل مع سيرفرات FTP مثله كمثل الويب العادي

ولكن بدل استخدام HttpWebReauset يتم استعمال

FtpWebRequset لهذا الغرض ، ويوجد برتوكولات

خاصة غير POST, GET ,HEAD ...etc[/COLOR]

--

البروتوكولات الموجودة للFtpWebRequset هي :



--

[COLOR="#2F4F4F"]وهذي class عملتها فيها اجرائات تستعمل طلبات ftp مثل Upload file , Download

سامحوني ردائة تصميم الكلاس فأنا كتبتها على السريع :[/COLOR]

PHP كود :
//All Copyright to Alshki LLah
    /// <summary>
    /// by this class you can use many function to manage your ftp host
    /// </summary>
    
class FTPManger
    
{
        const 
string FILE_PATTERN "-rw-r--r--";
        const 
string FOLDER_PATTERN "drwxr-xr-x";
        public 
string _host;
        
string _user_pass;
        
RichTextBox _statusTextBox null;


        
bool IsConnected getset; }

        public 
FTPManger(string ftpHoststring usernamestring password  RichTextBox statusTextBox)
        {
            
_host ftpHost;
            
_user username;
            
_pass password;
            
this._statusTextBox statusTextBox;

        }

        public 
enum GetFileMode
        
{
            
File,Folder
        
}

        
void setStatus(string text)
        {
            
_statusTextBox.Text += text;
            
_statusTextBox.SelectionStart _statusTextBox.Text.Length;
            
_statusTextBox.ScrollToCaret();
        }

        
#region "Getfiles"

        
public bool TryConnect()
        {
            
FtpWebRequest ftpReq = (FtpWebRequest)WebRequest.Create(_host);
            
ftpReq.Credentials = new NetworkCredential(_user_pass);
            
ftpReq.Method WebRequestMethods.Ftp.ListDirectoryDetails;

            
FtpWebResponse response =null;
            try
            {
                
response = (FtpWebResponse)ftpReq.GetResponse();
                
Stream responseStream response.GetResponseStream();
                
StreamReader reader = new StreamReader(responseStream);


                
IsConnected true;
                
setStatus("\n" "Connected OK , status code : " response.StatusDescription);
                return 
true;
            }
            catch
            {
                
IsConnected false;
                
_statusTextBox.Text += "\n" "Error while connecting";
                return 
false;
            }
        }


        public 
void getAllFilesAndFolder(ListView filesList)
        {
            
filesList.Items.Clear();
            
//get file
            
foreach (string file in GetFiles(FTPManger.GetFileMode.File))
            {
                
filesList.Items.Add(file).SubItems.Add("File");
            }
            
//get folder
            
foreach (string folder in GetFiles(FTPManger.GetFileMode.Folder))
            {
                
filesList.Items.Add(folder).SubItems.Add("Folder");
            }
        }


        public 
IEnumerable GetFiles(GetFileMode mode)
        {
            
FtpWebRequest ftpReq = (FtpWebRequest)WebRequest.Create(_host);
            
ftpReq.Credentials = new NetworkCredential(_user_pass);
            
ftpReq.Method WebRequestMethods.Ftp.ListDirectoryDetails;

            
FtpWebResponse response = (FtpWebResponseftpReq.GetResponse();
            
Stream responseStream response.GetResponseStream();
            
StreamReader reader = new StreamReader(responseStream);  

            while (!
reader.EndOfStream)
            {
                
string data reader.ReadLine();
                
string[] files data.Split(' ');

                
//اذا كان المحتوى الحالي عبارة عن ملف
                
if (files[0] == FILE_PATTERN && mode == GetFileMode.File)
                {
                    for (
int i 0files.Lengthi++)
                    {
                        if (
files[i].Contains(":"))
                        {
                            
string str "";
                            for (
int q 1files.Lengthq++)
                            {
                                
str += " " files[q];
                            }
                            yield return 
str.Trim();
                        }
                    }
                }

                if (
files[0] == FOLDER_PATTERN && mode == GetFileMode.Folder)
                {
                    for (
int i 0files.Lengthi++)
                    {
                        if (
files[i].Contains(":"))
                        {
                            
string str "";
                            for (
int q 1files.Lengthq++)
                            {
                                
str += " " files[q];
                            }
                            yield return 
str.Trim();
                        }
                    }
                }

            }
        }

        
#endregion

        #region "upload"

        
public void UploadFile(string FTPnewfileName ,string filePath)
        {
            if (
IsConnected)
            {
                
FtpWebRequest ftpReq = (FtpWebRequest)WebRequest.Create(_host "/" FTPnewfileName);
                
ftpReq.Credentials = new NetworkCredential(_user_pass);
                
ftpReq.Method WebRequestMethods.Ftp.UploadFile;

                
byte[] data System.IO.File.ReadAllBytes(filePath);

                
ftpReq.ContentLength data.Length;
                
System.IO.Stream st ftpReq.GetRequestStream();
                
st.Write(data0data.Length);
                
st.Close();

                
FtpWebResponse response null;
                try
                {
                    
response = (FtpWebResponse)ftpReq.GetResponse();
                    
setStatus"\n\n\n" "Upload File Complete, status : " response.StatusDescription);
                }
                catch
                {
                    
setStatus"\n\n\n""Upload File Faild");
                }
            }
            else
            {
                
setStatus("\n\n\n"+"Not Connected!!");
            }
        }
        
#endregion

        #region "download"
        
public void DownloadFile(string ftpFilePath string localDestinationFilePath)
        {
            if (
IsConnected)
            {
                
int bytesRead 0;
                
byte[] buffer = new byte[999]; //مخزن البايت

                
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpFilePath);
                
request.Credentials = new NetworkCredential(_user_pass);
                
request.Method WebRequestMethods.Ftp.DownloadFile;

                
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
                
Stream reader response.GetResponseStream();
                
FileStream fileStream = new FileStream(localDestinationFilePathFileMode.OpenOrCreate);

                try
                {
                    while (
true)
                    {
                        
bytesRead reader.Read(buffer0buffer.Length);

                        if (
bytesRead == 0)
                            break;

                        
fileStream.Write(buffer0bytesRead);
                    }
                    
fileStream.Close();
                    
setStatus"\n\n\n" "Downloaded Completed!!");
                }
                catch { 
setStatus"\n\n\n" "Download file filed"); }
            }
            else
            {
                
setStatus("Not Connected!!");
            }
        }
        
#endregion

        #region "delete folder"
        
public void DeleteFolder(string folderURL)
        {
            if (
IsConnected)
            {
                
FtpWebRequest ftpReq = (FtpWebRequest)WebRequest.Create(folderURL);
                
ftpReq.Credentials = new NetworkCredential(_user_pass);
                
ftpReq.Method WebRequestMethods.Ftp.RemoveDirectory;
                
ftpReq.KeepAlive true;

                try
                {
                    
FtpWebResponse ftpRes = (FtpWebResponse)ftpReq.GetResponse();
                    
setStatus("\n\n\n" "Folder Deleted!!");
                }
                catch
                {
                    
setStatus("\n\n\n" "Cannot delete folder");
                }
            }
            else
            {
                
setStatus("\n\n\n" "Not Connected!!");
            }
        }

        
#endregion

        #region delete file


        
public void DeleteFile(string fileURL)
        {
            if (
IsConnected)
            {
                
FtpWebRequest ftpReq = (FtpWebRequest)WebRequest.Create(fileURL);
                
ftpReq.Credentials = new NetworkCredential(_user_pass);
                
ftpReq.Method WebRequestMethods.Ftp.DeleteFile;

                try
                {
                    
FtpWebResponse response = (FtpWebResponse)ftpReq.GetResponse();
                    
setStatus("\n\n\n" "Deleting File Complete, status : " response.StatusDescription);
                }
                catch
                {
                    
setStatus"\n\n\n" "Cannot delete file");
                }

            }
            else
            {
                
setStatus("\n\n\n" "Not Connected!!");
            }
        }
        
#endregion

        #region rename file


        
public void renemeFile(string fileURL,string renemeTo)
        {
            if (
IsConnected)
            {
                
FtpWebRequest ftpReq = (FtpWebRequest)WebRequest.Create(fileURL);
                
ftpReq.Credentials = new NetworkCredential(_user_pass);
                
ftpReq.Method WebRequestMethods.Ftp.Rename;
                
ftpReq.RenameTo renemeTo;

                try
                {
                    
FtpWebResponse response = (FtpWebResponse)ftpReq.GetResponse();
                    
setStatus("\n\n\n" "Renamed File Complete, status : " response.StatusDescription);
                }
                catch
                {
                    
setStatus("\n\n\n" "Cannot rename file");
                }

            }
            else
            {
                
setStatus("\n\n\n" "Not Connected!!");
            }
        }
        
#endregion

        #region "make folder"
        
public void MakeFolder(string folderURL)
        {
            if (
IsConnected)
            {
                
FtpWebRequest ftpReq = (FtpWebRequest)WebRequest.Create(folderURL);
                
ftpReq.Credentials = new NetworkCredential(_user_pass);
                
ftpReq.Method WebRequestMethods.Ftp.MakeDirectory;

                try
                {
                    
FtpWebResponse response = (FtpWebResponse)ftpReq.GetResponse();
                    
setStatus("\n\n\n" "Folder created !!!, status : " response.StatusDescription);
                }
                catch
                {
                    
setStatus"\n\n\n" "Cannot create folder");
                }

            }
            else
            {
                
setStatus"\n\n\n" "Not Connected!!");
            }
        }

        
#endregion

    



--

وهذا المثال :




لاحظ انا عملت هوست ftp خاص عشان تجربو عليه



--

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

--



{يتبع الجزء التاسع} >>>

[/b]


الملفات المرفقة
.zip   FTP requset.zip (الحجم : 108.84 ك ب / التحميلات : 86)
الرد }}}
تم الشكر بواسطة: السندبااد , السندبااد , أسامة , Fantastico , invocker
#5
تاسعا :- الخاتمة


[COLOR="#800000"]في النهاية اتمنى انكم استفدم من هذه المقالة

واتمنى ان تكون المقالة مرجعا لكل من يريد

تعلم كيفية ارسال الطلبات ، فهذا شيئ مهم

يمكنك من ارسال واستقبال اي شي من اي موقع

والحصول على خدمات المواقع

فنحن قمنا مثلا في البداية باستعمال موقع تحويل bbcodeHtml

لتحويل اكواد BBcode الى Html ، ثم قمنا برفع ملف الى مركز الرفع من برنامجنا

فيمكنك استعمال الطلبات للحصول على الخدمات التي تقدمها المواقع

وبإستعمال التحليل نكون قد حصلنا على كل مانحتاجه للتعامل مع الويب

والتحليل هو عنوان مقالتنا القادمة ، نلقاكم بخير
[/COLOR]
الرد }}}
تم الشكر بواسطة: nani49 , السندبااد , أسامة
#6
تم بحمد الله
الرد }}}
تم الشكر بواسطة:
#7
تم بحمد الله
الرد }}}
تم الشكر بواسطة:
#8
السلام عليكم

سوف يتم تمديد المسابقة لنهاية ثالث ايام العيد السعيد

يعطيك العافية
(( يَا أَيَّتُهَا النَّفْسُ الْمُطْمَئِنَّةُ ارْجِعِي إِلَى رَبِّكِ رَاضِيَةً مَرْضِيَّةً فَادْخُلِي فِي عِبَادِي وَادْخُلِي جَنَّتِي ))

الرد }}}
تم الشكر بواسطة: ابو روضة
#9
الله يعطيك العافيه ويبارك فيك ويجزيك كل خير
الرد }}}
تم الشكر بواسطة:
#10
abulayth كتب :السلام عليكم

سوف يتم تمديد المسابقة لنهاية ثالث ايام العيد السعيد

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

الحمدلله اخي خلصتني من الضغط الشديد

+ الرد مانحذف من الاساس بس كان مدموج ويا المشاركة الاولى !!! شلون مادري
الرد }}}
تم الشكر بواسطة: معاند الحظ


المواضيع المحتمل أن تكون متشابهة .
الموضوع : الكاتب الردود : المشاهدات : آخر رد
  [سلسلة التحكم] {4} - التحكم عن بعد بواسطة خدمة الويب الشاكي لله 7 9,569 12-07-21, 02:34 PM
آخر رد: devante.celvin
  [سلسلة التحكم] {5} - التحكم بالمصباح بواسطة الـ USB و Arduino الشاكي لله 12 25,186 30-12-19, 01:38 AM
آخر رد: mohammed abdalsamed
  [سلسلة التحكم] {3} - خدمة الويب (Web Service) الشاكي لله 9 12,811 25-09-19, 05:47 PM
آخر رد: al9atl
  تجميعية مقالات [سلسلة التحكم] الشاكي لله 10 7,503 15-07-19, 09:14 AM
آخر رد: mrsalnet
  التعامل مع ملفات xml بلغتي C#&VB Sajad 7 14,053 08-11-17, 10:21 AM
آخر رد: nani49
  [C#.NET] سلسلة حلقات نضف كودك Devahmedsalim 1 2,625 10-10-17, 11:28 PM
آخر رد: nani49
  [سلسلة ادوات المبرمج] {2} - اداة تحليل صفحات الويب HAPXPathFinder الشاكي لله 10 8,492 30-08-17, 06:49 PM
آخر رد: ابو روضة
  [سلسلة التحكم] {2} - التحكم بواسطة Remoting الشاكي لله 8 10,353 06-12-16, 04:22 PM
آخر رد: الشاكي لله
  [سلسلة التعامل مع الويب] تحليل الصفحات باستخدام HtmlAgilityPack الشاكي لله 9 7,024 25-09-16, 12:19 PM
آخر رد: ابراهيم كركوكي
  [سلسلة التحكم] {1} - طرق التحكم في البرامج الشاكي لله 7 8,115 12-02-16, 10:16 PM
آخر رد: nani49

التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم