برمجة المقبس في C++

Brmjt Almqbs Fy C



أصبحت برمجة المقبس موضوعًا مهمًا في مجال شبكات الكمبيوتر. يتضمن إنشاء اتصال بين العقدتين والخادم والعميل للتواصل مع بعضهما البعض دون أي انقطاع. يعمل الخادم كمستمع في قناة الاتصال ويستمع إلى العميل على منفذ معين على عنوان IP. ومن ناحية أخرى، يعمل العميل كمتواصل في قناة الاتصال. يتصل العميل بالخادم من أجل إنشاء اتصال وإجراء اتصال بالخادم. تهدف هذه المقالة إلى تقديم دليل شامل ومفصل لبرمجة المقبس في لغة C++، يغطي الأساسيات، ويقدم أمثلة عملية، ويقدم شرحًا مفصلاً للكود.

إنشاء نموذج العميل والخادم

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

1. جانب الخادم







الكود الخاص بجانب الخادم من النموذج موضح فيما يلي. دعونا نرى ما يحدث في الكود:



#تشمل
#تشمل
#تشمل
#تشمل

استخدام مساحة الاسم الأمراض المنقولة جنسيا ;

#تعريف المنفذ 8080
#حدد MAX_BUF_SIZE 1024

كثافة العمليات رئيسي ( ) {
كثافة العمليات ser_socket، cli_socket ;
البنية sockaddr_in ser_address، cli_address ;
شار buf [ MAX_BUF_SIZE ] = { 0 } ;

لو ( ( ser_socket = قابس كهرباء ( AF_INET، SOCK_STREAM، 0 ) ) == - 1 ) {
خطأ ( 'خطأ في إنشاء المقبس' ) ;
مخرج ( EXIT_FAILURE ) ;
}

ser_address. sin_family = OF_INET ;
ser_address. sin_addr . s_addr = INADDR_ANY ;
ser_address. sin_port = htons ( ميناء ) ;

لو ( ربط ( be_socket, ( البنية com.sockaddr * ) & عنوان_الخادم, حجم ( ser_address ) ) == - 1 ) {
خطأ ( 'فشل في الارتباط' ) ;
مخرج ( EXIT_FAILURE ) ;
}

لو ( يستمع ( be_socket, 3 ) == - 1 ) {
خطأ ( 'فشل في الاستماع' ) ;
مخرج ( EXIT_FAILURE ) ;
}

cout << 'الخادم يستمع على المنفذ' << ميناء << '... ' ;

socklen_t cli_address_len = حجم ( cli_address ) ;
لو ( ( cli_socket = يقبل ( be_socket, ( البنية com.sockaddr * ) & عنوان, & cli_address_len ) ) == - 1 ) {
خطأ ( 'فشل في القبول' ) ;
مخرج ( EXIT_FAILURE ) ;
}

يقرأ ( cli_socket، buf، MAX_BUF_SIZE ) ;
cout << 'رسالة العميل هي:' << buf << endl ;

يرسل ( cli_socket, ''رسالة الخادم'' , سترلين ( ''رسالة الخادم'' ) , 0 ) ;

يغلق ( cli_socket ) ;
يغلق ( ser_socket ) ;

يعود 0 ;
}

المثال الموضح هو الكود من جانب الخادم لبرنامج C++. يعمل هذا الرمز مع خادم TCP بسيط للاستماع للاتصالات على منفذ واحد محدد. عندما يتم إنشاء الاتصال بنجاح، سيتلقى الخادم رسالة مرسلة من العميل. بعد ذلك، يقوم بطباعته على وحدة التحكم وإرسال رسالة استجابة إلى العميل. دعونا نفهم كل سطر من التعليمات البرمجية.



يبدأ البرنامج بتضمين المكتبات: 'iostream' لتعريفات الإدخال/الإخراج القياسية، و'cstring' لوظائف معالجة السلسلة، و'unistd.h' لتوفير الوصول إلى واجهة برمجة تطبيقات نظام التشغيل POSIX، و'arpa/inet.h' لـ تنفيذ عمليات الإنترنت. العبارة '#define PORT 8080' تعني أنها تحدد رقم المنفذ 8080 الذي سيستمع إليه الخادم. '#define MAX_BUF_SIZE 1024' يعني الحد الأقصى لحجم المخزن المؤقت للبيانات الواردة وهو 1024.





في الوظيفة الرئيسية، تتم تهيئة متغيرين، 'ser_socket' و'cli_socket'، لتمثيل كل من الخادم والعميل، على التوالي. تتم تهيئة المتغيرات الثلاثة الأخرى وهي 'sockaddr_in' و'ser_address' و'cli_address' من النوع 'struct' كهياكل عناوين للخادم والعميل. بعد ذلك، تتم تهيئة المخزن المؤقت المسمى 'buf' والذي يقوم بتخزين البيانات الواردة من العميل.

تقوم وظيفة المقبس () في حالة 'if' بإنشاء مقبس TCP جديد. يشير AF_INET إلى IPv4، ويمثل SOCK_STREAM مقبس TCP الموثوق والموجه نحو الاتصال، ويتم إعطاء الوسيطة الأخيرة وهي 0 لتحديد بروتوكول TCP الافتراضي، ويقبل INADDR_ANY الاتصالات على أي عنوان IP، ويقوم htons (PORT) بتحويل رقم المنفذ من ترتيب البايت المضيف لترتيب البايت على الشبكة.



نظرًا لأن كل شيء تم تعريفه بشكل صحيح، فإن الخطوة التالية هي إعداد الخادم كقائمة على المنفذ المحدد وقبول الاتصالات على أي واجهة شبكة. يتم توفير المقبس بالمعلومات الموجودة في 'ser_address' بواسطة طريقة bind(). نطبع خطأ وننهي العملية في حالة فشل الربط. تفتح وظيفة Accept () مقبسًا جديدًا للاتصال بالعميل، بينما تقوم وظيفة الاستماع () بتوجيه الخادم لانتظار الاتصالات الواردة. إذا فشلت وظيفة Accept()، فستتم طباعة رسالة الخطأ وستخرج الوظيفة.

بعد ذلك، يقرأ الخادم رسالة العميل باستخدام وظيفة القراءة () في المخزن المؤقت 'buf' ثم يطبعها على وحدة التحكم. يتم استخدام وظيفة الإرسال () بواسطة الخادم لإرسال رسالة ردًا على العميل. وأخيرًا، باستخدام Close()، يغلق الخادم مقبس العميل، وينهي البرنامج بحيث يتم إغلاق جميع الاتصالات بشكل صحيح ولا يكون هناك احتمال لخرق البيانات.

2. جانب العميل

الآن، دعونا نرى ما يحدث في نموذج العميل:

#تشمل
#تشمل
#تشمل
#تشمل

#تعريف المنفذ 8080
#تعريف SERVER_IP '127.0.0.1'

كثافة العمليات رئيسي ( ) {
كثافة العمليات cli_socket ;
البنية sockaddr_in ser_address ;
مقدار ثابت شار * رسالة = 'العميل يرسل تحياته!' ;

لو ( ( cli_socket = قابس كهرباء ( AF_INET، SOCK_STREAM، 0 ) ) == - 1 ) {
خطأ ( 'خطأ في إنشاء المقبس' ) ;
مخرج ( EXIT_FAILURE ) ;
}

ser_address. sin_family = OF_INET ;
ser_address. sin_port = htons ( ميناء ) ;

لو ( inet_pton ( AF_INET، SERVER_IP، & ser_address. sin_addr ) <= 0 ) {
خطأ ( 'عنوان خاطئ' ) ;
مخرج ( EXIT_FAILURE ) ;
}

لو ( يتصل ( cli_socket, ( البنية com.sockaddr * ) & عنوان_الخادم, حجم ( ser_address ) ) == - 1 ) {
خطأ ( 'فشل الاتصال' ) ;
مخرج ( EXIT_FAILURE ) ;
}
يرسل ( cli_socket، رسالة، سترلين ( رسالة ) , 0 ) ;

شار buf [ 1024 ] = { 0 } ;
يقرأ ( cli_socket، بوف، حجم ( buf ) ) ;
الأمراض المنقولة جنسيا :: cout << 'استجابة الخادم:' << buf << الأمراض المنقولة جنسيا :: endl ;

يغلق ( cli_socket ) ;
يعود 0 ;
}

دعونا نرى كل سطر من التعليمات البرمجية لفهم كيفية عمل البرنامج.

يتم أيضًا تضمين نفس المكتبات الأربع - iostream، وcstring، وunistd.h، وarpa/inet.h - على جانب العميل. يتم أيضًا تعريف رقم المنفذ مع عنوان IP الخاص بالمضيف المحلي 127.0.0.1. يتم إعطاء الرسالة التي يجب تسليمها إلى الخادم. يحتاج العميل والخادم إلى إنشاء اتصال كخطوة التالية:

'إذا ((client_socket = مقبس (AF_INET, SOCK_STREAM, 0)) == -1);' يقوم بإنشاء مأخذ توصيل لـ IPv4 بنوع دفق والبروتوكول الافتراضي TCP. يقوم perror() بطباعة تفاصيل الخطأ إذا فشلت وظيفة المقبس() في إنشاء اتصال والخروج من البرنامج.

'server_address.sin_port = htons(PORT);' يضبط رقم المنفذ بعد التحويل إلى ترتيب بايت الشبكة. بعد ذلك، تظهر هنا رسالة فشل أخرى وهي 'العنوان الخاطئ' والتي تتم طباعتها إذا كان هناك خطأ ما في العنوان. من خلال تحديد العنوان في 'ser_address'، سيقوم العميل بالاتصال بالخادم. إذا فشل الاتصال، تتم طباعة تفاصيل الخطأ. ستقوم الدالة send() بنقل الرسالة إلى الخادم، مع التأكد من أنها لا تحتوي على أي علامة.

لتلقي استجابة من الخادم وتخزينها، تتم تهيئة مخزن مؤقت يسمى 'buf' من النوع 'char'. تقرأ الدالة read() استجابة الخادم في المخزن المؤقت. وأخيرًا، تتم طباعة استجابة الخادم على وحدة التحكم. أخيرًا، يتم إغلاق الاتصال باستخدام عبارة Close() لإنهاء المقبس. وفيما يلي إخراج البرنامج:

خاتمة

تعد برمجة المقبس جزءًا مهمًا من اتصالات الشبكة في علوم الكمبيوتر. فهو يتيح تطوير التطبيقات التي يمكنها التواصل عبر الشبكة، مما يتيح نطاقًا واسعًا من الإمكانيات بدءًا من بنيات خادم العميل البسيطة وحتى الأنظمة الموزعة المنظمة. عند إنشاء مأخذ توصيل في سياق برمجة، يجب على البرنامج تكوين خصائص نقطة النهاية الخاصة به مثل البروتوكولات أو TCP أو UDP، وعنوان الشبكة مثل عنوان IP ورقم المنفذ. تتيح هذه المقابس للخوادم إرسال البيانات واستقبالها. توضح هذه المقالة مثالًا عمليًا عن كيفية عمل نموذج خادم العميل في برمجة المقبس.