English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

برمجة Socket Ruby

يقدم Ruby مستويين من الوصول إلى الخدمات الشبكية، حيث يمكنك الوصول إلى النظام التشغيل في الطبقة الأساسية، مما يسمح لك بتحقيق دعم الأسكربتات المتصلة وغير المتصلة.

يدعم Ruby بشكل متماثل بروتوكولات الشبكة للتطبيقات مثل FTP،HTTP وما إلى ذلك.

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

لنبدأ الآن في تعلم كيفية برمجة Socket Ruby

ما هو Sockets

عندما تقوم الطبقة التطبيقية بتبادل البيانات عبر الطبقة الترانزيتية، يواجه TCP وUDP مشكلة تقديم خدمات متوازية للعديد من عمليات التطبيق. قد تحتاج عدة اتصالات TCP أو عمليات تطبيقية إلى نقل البيانات عبر نفس منفذ البروتوكول TCP. من أجل التمييز بين عمليات التطبيق المختلفة والاتصالات، توفر العديد من أنظمة التشغيل لبرامج التطبيق واجهة تمييزية تُدعى Socket لبروتوكول TCP/IP، لتمييز بين اتصالات الشبكة المختلفة.

يتم إنشاء socket، ويتمتع بثلاثة معلمات رئيسية: عنوان IP الهدف للاتصال، البروتوكول المستخدم في الطبقة الترانزيتية (TCP أو UDP) والمنفذ المستخدم. يعني Socket "المنفذ". من خلال دمج هذه الثلاثة معلمات، يتم ربطها مع "منفذ" Socket، يمكن للطبقة التطبيقية من خلال واجهة socket التمييز بين اتصالات مختلفة من قبل عمليات تطبيقية أو الاتصالات الشبكية، وتحقيق خدمة متوازية لنقل البيانات.

تحليل مفردات Sockets:

الخياراتالوصف
النطاقيحدد عائلة البروتوكولات التي يتم استخدامها، عادةً PF_INET، PF_UNIX، PF_X25، إلخ.
النوعيحدد نوع socket: SOCK_STREAM أو SOCK_DGRAM، تعرف واجهة Socket أيضًا Socket برمجية (SOCK_RAW)، مما يسمح للبرنامج باستخدام بروتوكولات الطبقة السفلية.
protocolعادةً يتم تخصيصها 0.
hostnameمؤشر على واجهة الشبكة:
  • السلسلة، يمكن أن تكون اسم المضيف أو عنوان IP.

  • السلسلة "<broadcast>"، تُحدد عنوان INADDR_BROADCAST.

  • قيمة 0 طولها صفر، تُحدد INADDR_ANY.

  • عدد صحيح، يعني عنوان البايت للخادم.

المنفذالمنفذ هو رقم المنفذ، وكل خادم يستمع إلى اتصال العميل من خلال منفذ أو أكثر، يمكن أن يكون المنفذ منفذًا من نوع Fixnum، ويشمل اسم الخادم ومنفذ.

عميل بسيط

فيما يلي قمنا بكتابة مثال بسيط على العميل باستخدام اسم المضيف والمنفذ المقدر، يقدم فئة Ruby TCPSocket طريقة open لفتح socket.

TCPSocket.open(hosname, port) يفتح اتصال TCP.

بمجرد فتح اتصال Socket، يمكنك قراءته مثل جسم IO، بعد الانتهاء، تحتاج إلى إغلاق الاتصال مثل إغلاق ملف.

يوضح هذا المثال كيفية الاتصال بمضيف معين، والقراءة من socket، وإغلاق socket في النهاية:

عينة على الإنترنت

require 'socket'                     # Sockets هي مكتبة قياسية
 
hostname = 'localhost'
port = 2000
 
s = TCPSocket.open(hostname, port)
 
while line = s.gets                 # قراءة كل سطر من socket
  puts line.chop                        # طباعة إلى الشاشة
fin
s.close                                                                                 # إغلاق socket

خدمة بسيطة

يمكن استخدام فئة TCPServer في Ruby لإنشاء خدمة بسيطة. TCPServer هو obj مصنع TCPSocket.

الآن نستخدم TCPServer.open(hostname, port) لإنشاء obj TCPServer.

الآن نستدعي طريقة accept في TCPServer، التي تنتظر اتصال عميل على المنفذ المحدد وتعيد TCPSocket تمثيلًا للاتصال بالعميل.

عينة على الإنترنت

require 'socket'                                                                         # الحصول على مكتبة socket القياسية
 
server = TCPServer.open(2000)        # منفذ الاستماع للسوكيت هو 2000
loop {                                                                                 # خدمات العملية دائمًا
  client = server.accept                 # الانتظار على اتصال العميل
  client.puts(Time.now.ctime)         # إرسال الوقت إلى العميل
  client.puts "Closing the connection. Bye!"
  client.close                                                                                 # إغلاق اتصال العميل
}

الآن، قم بتشغيل الكود المشار إليه على الخادم و شاهد النتائج.

خدمة TCP متعددة العملاء

على الإنترنت، معظم الخدمات تحتوي على عدد كبير من اتصالات العملاء.

يمكن لفئة Thread في Ruby إنشاء خدمات متعددة السلاسل بسهولة، حيث يقوم سلسلة واحدة بتنفيذ اتصال العميل بينما ينتظر السلسلة الرئيسية اتصالات أخرى.

عينة على الإنترنت

require 'socket'                                                                                 # الحصول على مكتبة socket القياسية
 
server = TCPServer.open(2000)         # منفذ الاستماع للسوكيت هو 2000
loop {                                                                                         # خدمات العملية دائمًا
  Thread.start(server.accept) do |client|
    client.puts(Time.now.ctime)    #  إرسال الوقت إلى العميل
    client.puts "Closing the connection. Bye!"
    client.close                  #  إغلاق اتصال العميل
  fin
}

في هذا المثال، يعمل socket بشكل دائم، بينما يتم إنشاء thread جديد عند استقبال server.accept اتصال من العميل، ويبدأ في معالجة الطلب على الفور. ثم يعود البرنامج الرئيسي إلى الدوران وينتظر الاتصال الجديد.

متصفح ويب صغير

يمكننا استخدام مكتبة socket لإنشاء أي بروتوكول إنترنت. يظهر الكود التالي كيفية الحصول على محتوى الصفحة:

عينة على الإنترنت

require 'socket'
 
host = 'ar.oldtoolbag.com'      #  خادم الويب
port = 80                      #  منفذ HTTP الافتراضي
path = "/index.htm"            #  عنوان الملف الذي تريد الحصول عليه
 
#  هذا هو طلب HTTP
request = "GET #{path} HTTP/1.0\r\n\r\n"
 
socket = TCPSocket.open(host,port)  #  الاتصال بالخادم
socket.print(request)          #  إرسال الطلب
response = socket.read          #  قراءة الاستجابة الكاملة
#  تقسيم الاستجابة عند أول سطر فارغ إلى处 headers وbody
headers,body = response.split("\r\n\r\n", 2) 
print body                    #  عرض النتيجة

لإنشاء عميل مشابه للويب، يمكنك استخدام مكتبات مسبقًا مبنية لـ HTTP مثل Net::HTTP.

الكود التالي هو مكافئ للكود السابق:

عينة على الإنترنت

require 'net/http'            #  我们需要的库
host = 'ar.oldtoolbag.com'      #  web 服务器
path = '/index.htm' # الملف الذي نريده 
 
http = Net::HTTP.new(host) # إنشاء اتصال
headers, body = http.get(path) # طلب الملف
if headers.code == "200" # التحقق من رمز الحالة
  print body                        
else                                
  puts "#{headers.code} #{headers.message}" 
fin

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