يمنحك MinimalSocket مكتبة C++ حديثة لإعداد وإنشاء اتصالات مقبس tcp و udp ، بطريقة لا تعتمد على النظام الأساسي تمامًا. الأنظمة المدعومة هي: Windows وأي توزيعة Linux و MacOS .
يعرض قسم الميزات تفاصيل الميزات المتنوعة لبرنامج MinimalSocket . اقرأ الاستخدام والعينات لمعرفة مدى سهولة استخدام MinimalSocket .
هذا مشروع CMake ، تحقق من دعم CMake لترى كيف يمكن دمج هذه المكتبة.
تذكر أن تترك نجمة في حال وجدت هذه المكتبة مفيدة.
لم تترك نجما بالفعل؟ افعلها الآن ;)!
يتيح لك MinimalSocket إنشاء اتصالات TCP و UDP وإعدادها. يمكن إرسال الرسائل واستقبالها من حيث المخزن المؤقت للبايت أو السلاسل. في الواقع، هذه هي في الواقع الإمكانية الوحيدة التي تحتاجها للمقبس، حيث يمكن إجراء تسلسل للرسائل الأكثر تعقيدًا أو استيعابها من مخزن مؤقت للبايتات باستخدام أساليب مثل Google Protocol Buffers أو NanoPb، من بين طرق أخرى.
هذه هي أبرز خصائص MinimalSocket :
يلخص هذا الجدول الاختلافات بين سلوكيات الحظر وغير الحظر للمقبس التي يمكن إنشاؤها باستخدام MinimalSocket :
سلوك الحظر، يتم حظر المتصل حتى الانتهاء أو الوصول إلى المهلة (إذا تم تحديدها) | سلوك عدم الحظر، تعود الوظائف على الفور | |
---|---|---|
قبول عميل جديد (TCP فقط) | يتم استيعاب مؤشر ترابط المتصل حتى يطلب العميل الجديد الاتصال فعليًا أو يتم الوصول إلى المهلة (إن تم تحديد أي منها) | إذا تم بالفعل وضع طلب اتصال من العميل في قائمة الانتظار قبل استدعاء وظيفة القبول، فسيتم إرجاع معالج اتصال جديد، وإلا فسيتم إرجاع nullopt. |
تلقي رسالة جديدة (tcp و udp) | يتم استيعاب مؤشر ترابط المتصل حتى يتم إرسال رسالة جديدة إلى المقبس أو الوصول إلى المهلة (إن تم تحديد أي منها) | إذا تم إرسال رسالة ووضعها في قائمة الانتظار بالفعل في المخزن المؤقت للمأخذ قبل استدعاء وظيفة الاستلام، فسيتم إرجاع تلك الرسالة، وإلا فسيتم إرجاع رسالة فارغة. |
إرسال رسالة جديدة (tcp وudp) | في حالة عدم امتلاء المخزن المؤقت للمقبس وإمكانية استضافة الرسالة المراد إرسالها بالكامل، تتم كتابة الرسالة فعليًا في المخزن المؤقت وتعود الوظيفة على الفور تقريبًا. على العكس من ذلك، يتم امتصاص مؤشر ترابط المتصل حتى يتم ملء المساحة في المخزن المؤقت (حيث يتم استهلاك الرسائل من الجانب الآخر) وبعد ذلك تتم كتابة الرسالة فعليًا وتكتمل الوظيفة. | إذا كان هناك مساحة كافية في المخزن المؤقت للمأخذ، تتم كتابة الرسالة وتعود الوظيفة. وفي الحالة المعاكسة، تعود الدالة فورًا دون إرسال الرسالة فعليًا (يمكن إعادة محاولة الإرسال لاحقًا) |
لم تترك نجما بالفعل؟ افعلها الآن ;)!
لإنشاء خادم tcp كلاسيكي للحظر، تحتاج فقط إلى إنشاء كائن tcp::TcpServer :
# include < MinimalSocket/tcp/TcpServer.h >
MinimalSocket::Port port = 15768 ; // the port to bind
MinimalSocket::tcp::TcpServer< true > tcp_server (
port, MinimalSocket::AddressFamily::IP_V4);
افتحه:
// open the server: binds the port and start to listen on the port
bool success = tcp_server.open();
والآن أنت جاهز لقبول عملاء جدد:
// accepts the next client that will ask the connection
MinimalSocket::tcp::TcpConnectionBlocking accepted_connection =
tcp_server.acceptNewClient(); // blocking till a client actually asks the
// connection
يمكنك الآن تبادل الرسائل مع العميل المقبول عن طريق القيام بذلك ببساطة:
// receive a message
std:: size_t message_max_size = 1000 ;
std::string
received_message // resized to the nunber of bytes actually received
= accepted_connection.receive(message_max_size);
// send a message
accepted_connection.send( " a message to send " );
إذا كنت تريد بدلاً من ذلك خادمًا غير محظور، فيمكنك إنشاؤه بطريقة مماثلة:
MinimalSocket::Port port = 15768 ; // the port to bind
MinimalSocket::tcp::TcpServer< false > tcp_server (
port, MinimalSocket::AddressFamily::IP_V4);
tcp_server.open();
لن يكون إصدار الخادم هذا محظورًا، مما يعني أن وظيفة القبول ستعود فورًا:
// check if a client asked for the connection. If no, the function immediately
// returns a nullopt. On the contrary, the returned optional contains the
// handler to the connected client
std::optional<MinimalSocket::tcp::TcpConnectionBlocking>
maybe_accepted_connection = tcp_server.acceptNewClient();
لاحظ أنه على الرغم من أن الخادم في حد ذاته غير محظور، إلا أن معالج العميل المقبول في النهاية يتم حظره. يمكنك تحويله إلى مأخذ توصيل غير محظور أيضًا، عن طريق نقل المقبس إلى معالج غير محظور:
MinimalSocket::tcp::TcpConnectionNonBlocking accepted_connection_nn_block =
maybe_accepted_connection-> turnToNonBlocking ();
لإنشاء عميل tcp، تحتاج فقط إلى إنشاء كائن tcp::TcpClient :
# include < MinimalSocket/tcp/TcpClient.h >
MinimalSocket::Port server_port = 15768 ;
std::string server_address = " 192.168.125.85 " ;
MinimalSocket::tcp::TcpClient< true > tcp_client (
MinimalSocket::Address{server_address, server_port});
افتحه:
// Open the server. Here, the client will ask the connection to specified
// server. After that, the client will be actually connected.
bool success =
tcp_client.open(); // blocking till the connection is actually established
يمكنك الآن تلقي المعلومات وإرسالها باستخدام الخادم البعيد بمجرد القيام بذلك:
// send a message
tcp_client.send( " a message to send " );
// receive a message
std:: size_t message_max_size = 1000 ;
std::string
received_message // resized to the nunber of bytes actually received
= tcp_client.receive(message_max_size);
إذا كنت تريد بدلاً من ذلك عميلاً غير محظور، فيمكنك إنشاؤه واستخدامه بطريقة مماثلة:
MinimalSocket::Port server_port = 15768 ;
std::string server_address = " 192.168.125.85 " ;
MinimalSocket::tcp::TcpClient< false > tcp_client (
MinimalSocket::Address{server_address, server_port});
tcp_client.open();
std:: size_t message_max_size = 1000 ;
// non blocking receive: returns immediately with an empty message in case no
// new data were available, or with a non empty message in the contrary case
std::string received_message = tcp_client.receive(message_max_size);
لإنشاء مقبس UDP عادي، تحتاج فقط إلى إنشاء كائن udp::Udp :
# include < MinimalSocket/udp/UdpSocket.h >
MinimalSocket::Port this_socket_port = 15768 ;
MinimalSocket::udp::Udp< true > udp_socket (this_socket_port,
MinimalSocket::AddressFamily::IP_V6);
افتحه:
// Open the server. This will bind the specified port.
bool success = udp_socket.open();
يمكنك الآن تلقي المعلومات وإرسالها باستخدام مقابس UDP الأخرى:
// send a message to another udp
MinimalSocket::Address other_recipient_udp =
MinimalSocket::Address{ " 192.168.125.85 " , 15768 };
udp_socket.sendTo( " a message to send " , other_recipient_udp);
// receive a message from another udp reaching this one
std:: size_t message_max_size = 1000 ;
auto received_message = udp_socket.receive(message_max_size);
// check the sender address
MinimalSocket::Address other_sender_udp = received_message->sender;
// access the received message
std::string received_message_content // resized to the nunber of bytes
// actually received
= received_message->received_message;
يمكنك أيضًا أن تقرر "توصيل" مقبس UDP مفتوح بعنوان محدد. احذر من أن هذا يعني ببساطة أنه سيتم تصفية الرسائل الواردة من أقران آخرين، حيث أن مقابس UDP ليست موجهة للاتصال:
MinimalSocket::Address permanent_sender_udp =
MinimalSocket::Address{ " 192.168.125.85 " , 15768 };
MinimalSocket::udp::UdpConnected< true > udp_connected_socket =
udp_socket.connect(
permanent_sender_udp); // ownership of the underlying socket is
// transfered from udp_socket to
// udp_connected_socket, meaning that you can't
// use anymore udp_socket (unless you re-open
// it)
يمكنك الآن إرسال واستقبال البيانات دون الحاجة إلى تحديد المستلم/المرسل:
// receive a message
std:: size_t message_max_size = 1000 ;
std::string
received_message // resized to the nunber of bytes actually received
= udp_connected_socket.receive(message_max_size);
// send a message
udp_connected_socket.send( " a message to send " );
يمكنك أيضًا إنشاء واستخدام مقابس UDP غير المحظورة:
MinimalSocket::Port this_socket_port = 15768 ;
MinimalSocket::udp::Udp< false > udp_socket (
this_socket_port, MinimalSocket::AddressFamily::IP_V6);
udp_socket.open();
std:: size_t message_max_size = 1000 ;
// non blocking receive: returns immediately with an empty message in case no
// new data were available, or with a non empty message in the contrary case
//
// struct ReceiveStringResult {
// Address sender;
// std::string received_message;
// };
std::optional<MinimalSocket::ReceiveStringResult> received_message =
udp_socket.receive(message_max_size);
لم تترك نجما بالفعل؟ افعلها الآن ;)!
يمكن العثور على أمثلة لاستخدام مقابس TCP هنا، بينما تتم مناقشة نماذج UDP هنا.
انتباه!!! قد يتم حظر تنفيذ العينات في المرة الأولى بواسطة جدار الحماية الخاص بك: قم بإعداد جدار الحماية الخاص بك بشكل صحيح أو قم بتشغيل العينات باستخدام امتيازات المسؤول
لم تترك نجما بالفعل؟ افعلها الآن ;)!
من أجل استهلاك هذه المكتبة يمكنك الاعتماد على CMake. بتعبير أدق، يمكنك جلب هذه الحزمة وربطها بمكتبة MinimalSocket :
include (FetchContent)
set (BUILD_MinimalCppSocket_SAMPLES OFF CACHE BOOL "" FORCE) # you don't want the samples in this case
FetchContent_Declare(
min_sock
GIT_REPOSITORY https://github.com/andreacasalino/Minimal-Socket
GIT_TAG master
)
FetchContent_MakeAvailable(min_sock)
ثم قم بالارتباط بمكتبة MinimalSocket :
target_link_libraries ( ${TARGET_NAME}
MinimalSocket
)
يتم تضمين جميع الوحدات الخاصة بالنظام داخليًا ولا يتم كشفها. علاوة على ذلك، في نظام التشغيل Windows ، يتم ربط wsock32 و ws2_32 بشكل خاص ولا تحتاج إلى ربطهما مرة أخرى عند استخدام MinimalSocket .