GNU/Linux >> Belajar Linux >  >> Linux

Mengapa saya tidak melihat MSG_EOR untuk SOCK_SEQPACKET di linux?

Dengan SOCK_SEQPACKET unix domain sockets, satu-satunya cara untuk memotong pesan adalah jika buffer yang Anda berikan ke recvmsg() tidak cukup besar (dan dalam hal ini Anda akan mendapatkan MSG_TRUNC).

POSIX mengatakan bahwa soket SOCK_SEQPACKET harus menyetel MSG_EOR di akhir catatan, tetapi soket domain unix Linux tidak.

(Referensi:POSIX 2008 2.10.10 mengatakan SOCK_SEQPACKET harus mendukung catatan, dan 2.10.6 mengatakan batas catatan dapat dilihat oleh penerima melalui bendera MSG_EOR.)

Apa arti 'catatan' untuk protokol tertentu bergantung pada implementasi yang akan ditentukan.

Jika Linux mengimplementasikan MSG_EOR untuk soket domain unix, saya pikir satu-satunya cara yang masuk akal adalah dengan mengatakan bahwa setiap paket adalah catatan tersendiri, jadi selalu setel MSG_EOR (atau mungkin selalu setel saat tidak menyetel MSG_TRUNC), jadi itu akan ' toh jangan informatif.


Saat Anda membaca dokumen, SOCK_SEQPACKET berbeda dengan SOCK_STREAM dalam dua cara yang berbeda. Pertama -

Jalur transmisi data berbasis koneksi dua arah yang berurutan, andal, untuk datagram dengan panjang maksimum tetap; konsumen diharuskan untuk membaca seluruh paket dengan setiap panggilan sistem masukan .

-- socket(2) dari proyek halaman manual Linux

alias

Untuk soket berbasis pesan, seperti SOCK_DGRAM dan SOCK_SEQPACKET, seluruh pesan harus dibaca dalam satu operasi. Jika pesan terlalu panjang untuk dimuat dalam buffer yang disediakan, dan MSG_PEEK tidak disetel dalam argumen flags, kelebihan byte harus dibuang, dan MSG_TRUNC harus disetel dalam anggota msg_flags dari struktur msghdr.

-- recvmsg() dalam standar POSIX.

Dalam hal ini mirip dengan SOCK_DGRAM .

Kedua, setiap "datagram" (Linux) / "message" (POSIX) membawa bendera yang disebut MSG_EOR .

Bagaimanapun Linux SOCK_SEQPACKET untuk AF_UNIX tidak mengimplementasikan MSG_EOR . Dokumen saat ini tidak sesuai dengan kenyataan :-)

Diduga beberapa SOCK_SEQPACKET implementasi melakukan yang lain. Dan beberapa menerapkan keduanya. Sehingga mencakup semua kemungkinan kombinasi yang berbeda :-)

[1] Protokol berorientasi paket umumnya menggunakan pembacaan tingkat paket dengan semantik pemotongan / pembuangan dan tanpa MSG_EOR. Soket domain X.25, Bluetooth, IRDA, dan Unix menggunakan SOCK_SEQPACKET dengan cara ini.

[2] Protokol berorientasi rekaman umumnya menggunakan pembacaan aliran byte dan MSG_EOR

  • tidak ada visibilitas tingkat paket, tidak ada pemotongan / pembuangan. DECNet dan ISO TP menggunakan SOCK_SEQPACKET seperti itu.

[3] Hibrida paket/rekam umumnya menggunakan SOCK_SEQPACKET dengan pemotongan/pembuangan semantik pada level paket, dan paket terminasi rekaman ditandai dengan MSG_EOR. SPX dan XNS SPP menggunakan SOCK_SEQPACKET dengan cara ini.

https://mailarchive.ietf.org/arch/msg/tsvwg/9pDzBOG1KQDzQ2wAul5vnAjrRkA

Anda telah menunjukkan contoh paragraf 1.

Paragraf 2 juga berlaku untuk SOCK_SEQPACKET seperti yang didefinisikan untuk SCTP. Meskipun secara default menetapkan MSG_EOR di setiap sendmsg() . Opsi untuk menonaktifkan ini disebut SCTP_EXPLICIT_EOR .

Paragraf 3, yang paling konsisten dengan dokumen, tampaknya merupakan kasus yang paling tidak jelas.

Dan bahkan dokumen tidak konsisten dengan dirinya sendiri.

Jenis soket SOCK_SEQPACKET mirip dengan jenis SOCK_STREAM, dan juga berorientasi koneksi. Satu-satunya perbedaan antara jenis ini adalah bahwa batas rekaman dipertahankan menggunakan jenis SOCK_SEQPACKET . Sebuah record dapat dikirim menggunakan satu atau lebih operasi output dan diterima menggunakan satu atau lebih operasi input, tetapi satu operasi tidak pernah mentransfer bagian dari lebih dari satu record. Batas rekaman dapat dilihat oleh penerima melalui flag MSG_EOR dalam flag pesan yang diterima yang dikembalikan oleh fungsi recvmsg(). -- Standar POSIX


Bukan itu gunanya MSG_EOR.

Ingat bahwa API soket adalah abstraksi dari sejumlah protokol yang berbeda, termasuk soket sistem file UNIX, pasangan soket, TCP, UDP, dan banyak protokol jaringan yang berbeda, termasuk X.25 dan beberapa yang sama sekali terlupakan.

MSG_EOR adalah untuk menandakan akhir catatan di mana itu masuk akal untuk protokol yang mendasarinya. Yaitu. itu untuk meneruskan pesan ke lapisan berikutnya di bawah bahwa "ini melengkapi catatan". Ini dapat mempengaruhi misalnya, buffering, menyebabkan pembilasan buffer. Namun jika protokol itu sendiri tidak memiliki konsep "catatan", tidak ada alasan untuk mengharapkan bendera tersebut disebarkan.

Kedua, jika menggunakan SEQPACKET Anda harus membaca seluruh pesan sekaligus. Jika tidak, sisanya akan dibuang. Itu didokumentasikan. Secara khusus, MSG_EOR tidak bendera untuk memberi tahu Anda bahwa ini adalah bagian terakhir dari paket.

Saran:Anda jelas menulis versi non-SEQPACKET untuk digunakan di MacOS. Saya sarankan Anda membuang versi SEQPACKET karena hanya akan menggandakan beban pemeliharaan dan pengkodean. SOCK_STREAM baik untuk semua platform.


Linux
  1. Mengapa Linux? – Beberapa Alasan Untuk Mengkonversi Ke Linux

  2. Linux – Mengapa Kami Menggunakan Su – Dan Bukan Hanya Su?

  3. Linux – Mengapa Setuid Tidak Bekerja??

  1. Linux – Mengapa Es_mx Lokal Bekerja Tapi Tidak Es?

  2. Mengapa tidak ada API DirectX untuk Linux?

  3. Mengapa pr_debug dari kernel Linux tidak memberikan hasil apa pun?

  1. Mengapa kebutuhan saya akan kontrol membuat saya beralih ke Linux

  2. Mengapa tidak ada pengelola paket yang benar-benar terpadu untuk Linux?

  3. Linux - Bagaimana saya bisa melihat apa yang menunggu disk IO