accept(2)

الاسم
accept, accept4 - قبول اتصال على مقبس

المكتبة
مكتبة سي المعيارية (libc، -lc)

موجز
#include <sys/socket.h>

int accept(int sockfd, struct sockaddr *_Nullable restrict addr,
           socklen_t *_Nullable restrict addrlen);

#define _GNU_SOURCE             /* See feature_test_macros(7) */
#include <sys/socket.h>

int accept4(int sockfd, struct sockaddr *_Nullable restrict addr,
           socklen_t *_Nullable restrict addrlen, int flags);

الوصف
استدعاء النظام accept() يُستخدم مع أنواع المقابس القائمة على الاتصال (SOCK_STREAM, SOCK_SEQPACKET). يستخرج أول طلب اتصال في قائمة انتظار الاتصالات المعلقة للمقبس المستمع، sockfd، وينشئ مقبسًا متصلًا جديدًا، ويعيد واصف ملف جديد يشير إلى ذلك المقبس. المقبس المُنشأ حديثًا ليس في حالة الاستماع. المقبس الأصلي sockfd لا يتأثر بهذا الاستدعاء.

الوسيط sockfd هو مقبس تم إنشاؤه باستخدام socket(2)، وربطه بعنوان محلي باستخدام bind(2)، ويستمع للاتصالات بعد listen(2).

الوسيط addr هو مؤشر لبنية sockaddr. تُملأ هذه البنية بعنوان المقبس النظير، كما هو معروف لطبقة الاتصالات. التنسيق الدقيق للعنوان المُعاد addr يُحدد بواسطة عائلة عنوان المقبس (انظر socket(2) وصفحات الدليل الخاصة بالبروتوكول). عندما يكون addr NULL، لا يُملأ شيء؛ في هذه الحالة، لا يُستخدم addrlen، ويجب أن يكون NULL أيضًا.

الوسيط addrlen هو وسيط قيمة-نتيجة: يجب على المستدعي تهيئته ليحتوي على الحجم (بالبايت) للبنية المشار إليها بواسطة addr؛ عند العودة سيحتوي على الحجم الفعلي لعنوان النظير.

يُبتر العنوان المُعاد إذا كان المخزن المؤقت المقدم صغيرًا جدًا؛ وفي هذه الحالة، سيعيد addrlen قيمة أكبر مما تم تمريره للاستدعاء.

إذا لم تكن هناك اتصالات معلقة في قائمة الانتظار، ولم يكن المقبس مُعلّمًا كغير محظور، فإن accept() يحظر المستدعي حتى يظهر اتصال. إذا كان المقبس مُعلّمًا كغير محظور ولم تكن هناك اتصالات معلقة في قائمة الانتظار، فإن accept() يفشل مع الخطأ EAGAIN أو EWOULDBLOCK.

للإشعار بالاتصالات الواردة على مقبس، يمكنك استخدام select(2) أو poll(2) أو epoll(7). سيتم تسليم حدث قابل للقراءة عند محاولة اتصال جديد، ويمكنك بعد ذلك استدعاء accept() للحصول على مقبس لذلك الاتصال. بدلاً من ذلك، يمكنك ضبط المقبس لتسليم SIGIO عند حدوث نشاط على مقبس؛ انظر socket(7) للتفاصيل.

إذا كان flags يساوي 0، فإن accept4() هو نفسه accept(). يمكن إجراء عملية OR بت-wise على القيم التالية في flags للحصول على سلوك مختلف:

SOCK_NONBLOCK
    اضبط علامة حالة الملف O_NONBLOCK على وصف الملف المفتوح (انظر open(2)) المشار إليه بواسطة واصف الملف الجديد. استخدام هذه العلامة يوفر استدعاءات إضافية لـ fcntl(2) لتحقيق النتيجة نفسها.

SOCK_CLOEXEC
    اضبط علامة الإغلاق عند التنفيذ (FD_CLOEXEC) على واصف الملف الجديد. انظر وصف العلامة O_CLOEXEC في open(2) للأسباب التي تجعل هذا مفيدًا.

قيمة الإرجاع
عند النجاح، تعيد استدعاءات النظام هذه واصف ملف للمقبس المقبول (عدد صحيح غير سالب). عند الخطأ، يتم إرجاع -1، ويتم تعيين errno للإشارة إلى الخطأ، ويُترك addrlen دون تغيير.

  معالجة الأخطاء
يقوم Linux accept() (و accept4()) بتمرير أخطاء الشبكة المعلقة بالفعل على المقبس الجديد كرمز خطأ من accept(). يختلف هذا السلوك عن تطبيقات مقبس BSD الأخرى. للتشغيل الموثوق، يجب على التطبيق اكتشاف أخطاء الشبكة المُعرّفة للبروتوكول بعد accept() ومعاملتها مثل EAGAIN بإعادة المحاولة. في حالة TCP/IP، هذه هي ENETDOWN و EPROTO و ENOPROTOOPT و EHOSTDOWN و ENONET و EHOSTUNREACH و EOPNOTSUPP و ENETUNREACH.

الأخطاء

EAGAIN أو EWOULDBLOCK
    المقبس مُعلّم كغير محظور ولا توجد اتصالات لقبولها. يسمح POSIX.1-2001 و POSIX.1-2008 بإرجاع أي من الخطأين لهذه الحالة، ولا يتطلبان أن تكون هذه الثوابت بنفس القيمة، لذا يجب على التطبيق المحمول التحقق من كلا الاحتمالين.

EBADF
    sockfd ليس واصف ملف مفتوح.

ECONNABORTED
    أُحبط اتصال.

EFAULT
    الوسيط addr ليس في جزء قابل للكتابة من مساحة عنوان المستخدم.

EINTR
    تم مقاطعة استدعاء النظام بواسطة إشارة تم التقاطها قبل وصول اتصال صالح؛ انظر signal(7).

EINVAL
    المقبس لا يستمع للاتصالات، أو addrlen غير صالح (مثلًا، سالب).

EINVAL
    (accept4()) قيمة غير صالحة في flags.

EMFILE
    وُصل إلى الحد الأقصى لواصفات الملفات المفتوحة لكل عملية.

ENFILE
    وُصل إلى الحد الأقصى لإجمالي عدد الملفات المفتوحة على مستوى النظام.

ENOBUFS
ENOMEM
    ذاكرة حرة غير كافية. هذا يعني غالبًا أن تخصيص الذاكرة محدود بحدود مخزن المقبس المؤقت، وليس بذاكرة النظام.

ENOTSOCK
    واصف الملف sockfd لا يشير إلى مقبس.

EOPNOTSUPP
    المقبس المُشار إليه ليس من النوع SOCK_STREAM.

EPERM
    قواعد جدار الحماية تمنع الاتصال.

EPROTO
    خطأ بروتوكول.

بالإضافة إلى ذلك، قد يتم إرجاع أخطاء الشبكة للمقبس الجديد كما هو مُعرّف للبروتوكول. يمكن لأنوية Linux المختلفة إرجاع أخطاء أخرى مثل ENOSR و ESOCKTNOSUPPORT و EPROTONOSUPPORT و ETIMEDOUT. قد تظهر القيمة ERESTARTSYS أثناء التتبع.

الإصدارات
على Linux، المقبس الجديد المُعاد بواسطة accept() لا يرث أعلام حالة الملف مثل O_NONBLOCK و O_ASYNC من المقبس المستمع. يختلف هذا السلوك عن تطبيق مقابس BSD التقليدي. يجب ألا تعتمد البرامج المحمولة على وراثة أو عدم وراثة أعلام حالة الملف، ودائمًا تضبط صراحة جميع الأعلام المطلوبة على المقبس المُعاد من accept().

المعايير
POSIX.1-2024.

التاريخ

accept()
    POSIX.1-2001, SVr4, 4.4BSD (accept() ظهر أولاً في 4.2BSD).

accept4()
    POSIX.1-2024. Linux 2.6.28, glibc 2.10.

ملاحظات
قد لا يكون هناك اتصال منتظر دائمًا بعد تسليم SIGIO أو إرجاع select(2) أو poll(2) أو epoll(7) حدث قابلية للقراءة، لأن الاتصال قد أُزيل بواسطة خطأ شبكة غير متزامن أو خيط آخر قبل استدعاء accept(). إذا حدث هذا، فسيحظر الاستدعاء في انتظار وصول الاتصال التالي. لضمان عدم حظر accept() أبدًا، يجب أن تحتوي المقبس المُمرر sockfd على العلم O_NONBLOCK (انظر socket(7)).

بالنسبة لبعض البروتوكولات التي تتطلب تأكيدًا صريحًا، مثل DECnet، يمكن اعتبار accept() مجرد إزالة طلب الاتصال التالي من قائمة الانتظار دون تضمين تأكيد. يمكن تضمين التأكيد عن طريق قراءة أو كتابة عادية على واصف الملف الجديد، ويمكن تضمين الرفض عن طريق إغلاق المقبس الجديد. حاليًا، فقط DECnet لديها هذه الدلالات على Linux.

  النوع socklen_t
في تطبيق مقابس BSD الأصلي (وعلى أنظمة أقدم أخرى)، أُعلن الوسيط الثالث لـ accept() كـ int *. أراد مسودة معيار POSIX.1g تغييره إلى size_t *؛ لاحقًا، معايير POSIX و glibc 2.x لديها socklen_t *.

أمثلة
انظر bind(2).

انظر أيضًا
bind(2)، connect(2)، listen(2)، select(2)، socket(2)، socket(7)

ترجمة
تُرجمت هذه الصفحة من الدليل بواسطة زايد السعيدي <zayed.alsaidi@gmail.com>

هذه الترجمة هي وثيقة مجانية؛ راجع رخصة جنو العامة الإصدار 3 (https://www.gnu.org/licenses/gpl-3.0.html) أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات.

إذا وجدت أي أخطاء في ترجمة صفحة الدليل هذه، يرجى إرسال بريد إلكتروني إلى قائمة بريد المترجمين: kde-l10n-ar@kde.org.