send(2)

الاسم
send, sendto, sendmsg - إرسال رسالة على مقبس

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

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

ssize_t send(size_t size;
               int sockfd, const void buf[size], size_t size, int flags);
ssize_t sendto(size_t size;
               int sockfd, const void buf[size], size_t size, int flags,
               const struct sockaddr *dest_addr, socklen_t addrlen);
ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);

الوصف
استدعاءات النظام send() و sendto() و sendmsg() تُستخدم لنقل رسالة إلى مقبس آخر.

استدعاء send() يمكن استخدامه فقط عندما يكون المقبس في حالة connected (بحيث يكون المستلم المقصود معروفًا). الفرق الوحيد بين send() و write(2) هو وجود flags. مع وسيطة flags صفرية، يكون send() مكافئًا لـ write(2). أيضًا، الاستدعاء التالي

    send(sockfd, buf, size, flags);

يكافئ

    sendto(sockfd, buf, size, flags, NULL, 0);

الوسيطة sockfd هي واصف الملف للمقبس المُرسِل.

إذا استُخدم sendto() على مقبس في وضع الاتصال (SOCK_STREAM، SOCK_SEQPACKET)، تُتجاهل الوسيطتان dest_addr و addrlen (وقد يُرجع الخطأ EISCONN عندما لا تكونان NULL و0)، ويُرجَع الخطأ ENOTCONN عندما لا يكون المقبس متصلًا فعليًا. خلاف ذلك، يُعطى عنوان الهدف بواسطة dest_addr مع تحديد حجمه بواسطة addrlen. بالنسبة لـ sendmsg()، يُعطى عنوان الهدف بواسطة msg.msg_name، مع تحديد حجمه بواسطة msg.msg_namelen.

بالنسبة لـ send() و sendto()، توجد الرسالة في buf ويكون حجمها size. بالنسبة لـ sendmsg()، تُشير عناصر المصفوفة msg.msg_iov إلى الرسالة. يسمح استدعاء sendmsg() أيضًا بإرسال بيانات مساعدة (تُعرف أيضًا بمعلومات التحكم).

إذا كانت الرسالة طويلة جدًا بحيث لا يمكن تمريرها بشكل ذري عبر البروتوكول الأساسي، يُرجَع الخطأ EMSGSIZE، ولا تُنقَل الرسالة.

لا يوجد إشارة ضمنية لفشل التسليم في send(). تُشار إلى الأخطاء المُكتشفة محليًا بقيمة إرجاع -1.

عندما لا تتسع الرسالة في مخزن الإرسال المؤقت للمقبس، يُحجَز send() عادةً، إلا إذا وُضِع المقبس في وضع إدخال/إخراج غير محجوز. في الوضع غير المحجوز، سيفشل مع الخطأ EAGAIN أو EWOULDBLOCK في هذه الحالة. يمكن استخدام استدعاء select(2) لتحديد متى يمكن إرسال المزيد من البيانات.

  معامل العلامات (flags)
الوسيطة flags هي OR أحادي البت لصفر أو أكثر من الأعلام التالية.

MSG_CONFIRM (منذ Linux 2.3.15)
    أخبر طبقة الارتباط بحدوث تقدم أمامي: حصلت على رد ناجح من الجانب الآخر. إذا لم تحصل طبقة الارتباط على ذلك، فستُعيد استقصاء الجار بانتظام (مثلًا عبر ARP أحادي الإرسال). صالح فقط على مقابس SOCK_DGRAM و SOCK_RAW ومُطبَّق حاليًا فقط لـ IPv4 و IPv6. انظر arp(7) للتفاصيل.

MSG_DONTROUTE
    لا تستخدم بوابة لإرسال الحزمة، أرسل إلى المضيفين فقط على الشبكات المتصلة مباشرة. يُستخدم هذا عادةً فقط بواسطة برامج التشخيص أو التوجيه. هذا مُعرَّف فقط لعائلات البروتوكولات التي تُوجّه؛ مقابس الحزم لا تفعل ذلك.

MSG_DONTWAIT (منذ لينكس 2.2)
    يُفعّل العملية غير المحجوزة؛ إذا كانت العملية ستحجز، يُرجَع EAGAIN أو EWOULDBLOCK. يوفر هذا سلوكًا مشابهًا لتعيين العلم O_NONBLOCK (عبر عملية fcntl(2) F_SETFL)، لكنه يختلف في أن MSG_DONTWAIT هو خيار لكل استدعاء، بينما O_NONBLOCK هو إعداد على وصف الملف المفتوح (انظر open(2))، والذي سيؤثر على جميع الخيوط في العملية المُستدعية بالإضافة إلى العمليات الأخرى التي تحمل واصفات ملفات تُشير إلى نفس وصف الملف المفتوح.

MSG_EOR (منذ Linux 2.2)
    يُنهي سجلًا (عندما يكون هذا المفهوم مدعومًا، كما هو الحال لمقابس من النوع SOCK_SEQPACKET).

MSG_MORE (منذ Linux 2.4.4)
    المُستدعي لديه المزيد من البيانات لإرسالها. يُستخدم هذا العلم مع مقابس TCP للحصول على نفس تأثير خيار المقبس TCP_CORK (انظر tcp(7))، مع الفرق أن هذا العلم يمكن تعيينه على أساس كل استدعاء.

    منذ Linux 2.6، هذا العلم مدعوم أيضًا لمقابس UDP، ويُخبر النواة بتجميع جميع البيانات المُرسلة في استدعاءات مع تعيين هذا العلم في مخطط بيانات واحد يُنقَل فقط عند تنفيذ استدعاء لا يُحدد هذا العلم. (انظر أيضًا خيار المقبس UDP_CORK الموصوف في udp(7).)

MSG_NOSIGNAL (منذ Linux 2.2)
    لا تُنشئ إشارة SIGPIPE إذا أغلق النظير على مقبس موجه للتيار الاتصال. لا يزال الخطأ EPIPE يُرجَع. يوفر هذا سلوكًا مشابهًا لاستخدام sigaction(2) لتجاهل SIGPIPE، لكن بينما MSG_NOSIGNAL هي ميزة لكل استدعاء، فإن تجاهل SIGPIPE يُعيّن سمة عملية تؤثر على جميع الخيوط في العملية.

MSG_OOB
    يُرسل بيانات خارج النطاق على مقابس تدعم هذا المفهوم (مثلًا من النوع SOCK_STREAM)؛ يجب أن يدعم البروتوكول الأساسي أيضًا بيانات خارج النطاق.

MSG_FASTOPEN (منذ Linux 3.7)
    يحاول الفتح السريع لـ TCP (RFC7413) ويُرسل البيانات في SYN مثل مزيج من connect(2) و write(2)، عن طريق تنفيذ عملية connect(2) ضمنية. يُحجَز حتى تُخزَّن البيانات مؤقتًا ويُكمَل المصافحة. بالنسبة لمقبس غير محجوز، يُرجِع عدد البايتات المُخزَّنة مؤقتًا والمُرسلة في حزمة SYN. إذا لم تكن الكعكة متاحة محليًا، يُرجِع EINPROGRESS، ويُرسل SYN مع طلب كعكة الفتح السريع آليًا. يحتاج المُستدعي إلى كتابة البيانات مرة أخرى عندما يكون المقبس متصلًا. عند الأخطاء، يُعيّن نفس errno مثل connect(2) إذا فشلت المصافحة. يتطلب هذا العلم تمكين دعم عميل الفتح السريع لـ TCP على sysctl net.ipv4.tcp_fastopen.

    راجع خيار المقبس TCP_FASTOPEN_CONNECT في tcp(7) لنهج بديل.

  sendmsg()
تعريف البنية msghdr المستخدمة بواسطة sendmsg() هو كما يلي:

    struct msghdr {
        void         *msg_name;       /* Optional address */
        socklen_t     msg_namelen;    /* Size of address */
        struct iovec *msg_iov;        /* Scatter/gather array */
        size_t        msg_iovlen;     /* # elements in msg_iov */
        void         *msg_control;    /* Ancillary data, see below */
        size_t        msg_controllen; /* Ancillary data buffer size */
        int           msg_flags;      /* Flags (unused) */
    };

يُستخدم الحقل msg_name في مقبس غير متصل لتحديد العنوان الهدف لرزمة بيانات. يشير إلى مخزن يحتوي على العنوان؛ يجب تعيين الحقل msg_namelen إلى حجم العنوان. بالنسبة لمقبس متصل، يجب تحديد هذه الحقول كـ NULL و0 على التوالي.

تحدد الحقول msg_iov وmsg_iovlen مواقع التوزيع والتجميع، كما في writev(2).

يمكنك إرسال معلومات التحكم (البيانات المساعدة) باستخدام العضوين msg_control وmsg_controllen. الحد الأقصى لحجم مخزن التحكم الذي يمكن للنواة معالجته محدود لكل مقبس بالقيمة في /proc/sys/net/core/optmem_max؛ انظر socket(7). لمزيد من المعلومات حول استخدام البيانات المساعدة في نطاقات مقابس مختلفة، انظر unix(7) وip(7).

الحقل msg_flags يُتجاهل.

قيمة الإرجاع
عند النجاح، تُرجع هذه الاستدعاءات عدد البايتات المرسلة. عند الخطأ، يُرجع -1، ويُضبط errno للإشارة إلى الخطأ.

الأخطاء
هذه بعض الأخطاء القياسية التي تُنشئها طبقة المقبس. قد تُنشأ أخطاء إضافية وتُعاد من وحدات البروتوكول الأساسية؛ انظر صفحات الدليل الخاصة بها.

EACCES
    (لمقابس نطاق UNIX، التي تُحدد بمسار اسم) يُرفض إذن الكتابة على ملف المقبس الهدف، أو يُرفض إذن البحث لأحد أدلة بادئة المسار. (انظر path_resolution(7).)

    (لمقابس UDP) جرت محاولة للإرسال إلى عنوان شبكة/بث كما لو كان عنوانًا أحاديًا.

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

EAGAIN
    (مقابس رزم بيانات نطاق الإنترنت) المقبس المشار إليه بواسطة sockfd لم يكن مرتبطًا مسبقًا بعنوان، وعند محاولة ربطه بمنفذ مؤقت، تبيّن أن جميع أرقام المنافذ في نطاق المنافذ المؤقتة قيد الاستخدام حاليًا. انظر مناقشة /proc/sys/net/ipv4/ip_local_port_range في ip(7).

EALREADY
    فتح سريع آخر قيد التقدم.

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

ECONNRESET
    إعادة تعيين الاتصال من قبل النظير.

EDESTADDRREQ
    المقبس ليس في وضع الاتصال، ولا يوجد عنوان نظير مُضبط.

EFAULT
    عُنوان مساحة مستخدم غير صالح مُحدد لوسيط.

EINTR
    حدثت إشارة قبل إرسال أي بيانات؛ انظر signal(7).

EINVAL
    مُرر معامل غير صالح.

EISCONN
    المقبس في وضع الاتصال كان متصلاً بالفعل ولكن تم تحديد مستلم. (الآن إما يُرجع هذا الخطأ، أو يُتجاهل تحديد المستلم.)

EMSGSIZE
    نوع المقبس يتطلب إرسال الرسالة بشكل ذري، وحجم الرسالة المراد إرسالها جعل ذلك مستحيلاً.

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

ENOMEM
    لا توجد ذاكرة متاحة.

ENOTCONN
    المقبس غير متصل، ولم يُعطَ أي هدف.

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

EOPNOTSUPP
    بعض البتات في وسيط flags غير مناسبة لنوع المقبس.

EPIPE
    الطرف المحلي أُغلق على مقبس موجه للاتصال. في هذه الحالة، ستستقبل العملية أيضًا SIGPIPE ما لم يُضبط MSG_NOSIGNAL.

الإصدارات
وفقًا لـ POSIX.1-2001، يجب أن يكون الحقل msg_controllen من البنية msghdr من النوع socklen_t، والحقل msg_iovlen من النوع int، لكن glibc حاليًا يكتب كليهما كـ size_t.

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

MSG_CONFIRM هو امتداد لينكس.

التاريخ
4.4BSD, SVr4, POSIX.1-2001. (ظهر لأول مرة في 4.2BSD).

يصف POSIX.1-2001 فقط العلمين MSG_OOB وMSG_EOR. يضيف POSIX.1-2008 مواصفات لـ MSG_NOSIGNAL.

ملاحظات
انظر sendmmsg(2) للحصول على معلومات حول استدعاء نظام خاص بلينكس يمكن استخدامه لنقل رزم بيانات متعددة في استدعاء واحد.

العلل
قد يُرجع لينكس EPIPE بدلاً من ENOTCONN.

أمثلة
مثال على استخدام sendto() موضح في getaddrinfo(3).

انظر أيضًا
fcntl(2), getsockopt(2), recv(2), select(2), sendfile(2), sendmmsg(2), shutdown(2), socket(2), write(2), cmsg(3), ip(7), ipv6(7), socket(7), tcp(7), udp(7), unix(7)

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

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

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