Unix, SOCK_SEQPACKET и SOCK_DGRAM
Кажется, есть как минимум 3 различных типа локальных /unix сокетов (AF_UNIX
), SOCK_STREAM
, SOCK_DGRAM
и SOCK_SEQPACKET
.
Хотя я знаю, что SOCK_STREAM
дает вам двунаправленный байтовый поток, такой как TCP или двунаправленный канал, а два других дают вам API сообщений/пакетов, в чем разница между сокетом Unix SOCK_DGRAM
и SOCK_SEQPACKET
?
Поскольку они являются только локальными, я не могу придумать вескую причину, по которой кто-то мог бы реализовать SOCK_DGRAM
таким образом, чтобы он мог переупорядочивать пакеты.
Кроме того, SOCK_DGRAM
/SOCK_SEQPACKET
использует управление потоком, или сообщения могут быть отброшены в случае медленных читателей?
Ответы
Ответ 1
Вот хорошая статья о предполагаемом случае использования SOCK_SEQPACKET
, о том, что она действительно недоступна в семействах IP-протоколов и как вы можете получить то же самое с существующей семантикой TCP:
http://urchin.earth.li/~twic/Sequenced_Packets_Over_Ordinary_TCP.html
Обратите внимание, что SOCK_SEQPACKET
намного ближе поведению к SOCK_STREAM
, чем к SOCK_DGRAM
.
Ссылается на указанный веб-сайт:
Тип сокета SOCK_SEQPACKET похож на тип SOCK_STREAM и также ориентирован на соединение. Единственная разница между этими типы заключаются в том, что границы записей сохраняются с использованием Тип SOCK_SEQPACKET. Запись может быть отправлена с использованием одного или нескольких выходных данных операций и полученных с использованием одной или нескольких операций ввода, но одна операция никогда не передает части более чем одной записи. запись границы видны приемнику через флаг MSG_EOR в полученные флаги сообщений, возвращаемые функцией recvmsg(). это зависит от протокола, зависит ли максимальный размер записи.
Ответ 2
SOCK_SEQPACKET дает вам гарантии SOCK_STREAM (т.е. сохранение заказа, гарантированную доставку, отсутствие дублирования), но с очерченными границами пакетов, как SOCK_DGRAM. Таким образом, в основном это сочетание двух типов протоколов.
В семействе TCP/IP SCTP реализуется как SOCK_STREAM (TCP-like), так и SOCK_SEQPACKET. К сожалению, он не доступен в Windows.
Ответ 3
socket (2) предоставленная linux manpage: "DGRAM: датаграммы (без установления соединения, ненадежные сообщения), SEQPACKET: последовательный, надежный, [двусторонний] путь передачи данных на основе соединений для дейтаграмм". Значительная разница.
unix (7) linux-предоставленная manpage говорит: "SOCK_DGRAM для ориентированного на дейтаграммы сокета, который сохраняет границы сообщений [но не обязательно порядок] [...] SOCK_SEQPACKET, для ориентированный на соединение, который сохраняет границы сообщений и доставляет сообщения в том порядке, в котором они были отправлены.
Стандарт позволяет получить переупорядоченные пакеты с SOCK_DGRAM. (Другими словами, если ОС передаст их вам по порядку, это особенность, специфичная для реализации, или просто удачная синхронизация по времени.)
В реализации af_file/af_unix существует управление потоком, но это не обязательно должно коррелировать со стандартным заданным поведением.
Ответ 4
Подобно TCP и UDP-сокетам, существуют протоколы SCTP (протокол управления потоком), которые имеют две формы (один к одному) и (один для многих) между конечными точками. Один к одному использует SOCK_STREAM, а один для многих использует SOCK_SEQPACKET
Ответ 5
Я думаю, что основное отличие здесь в том, что SOCK_SEQPACKET
ориентирован на соединение, а SOCK_DGRAM
- нет.
Это в основном будет иметь значение на стороне сервера соединения (процесс, который прослушивает сокет UNIX), когда с ним разговаривают несколько клиентских процессов:
С SOCK_DGRAM
вы получите чередующиеся клиентские дейтаграммы прямо на слушающем сокете. С SOCK_SEQPACKET
вы бы породили отдельный клиентский сокет для каждого клиента, используя accept
, таким образом получая дейтаграммы от каждого клиента отдельно.
Цитирую man 3 accept
:
Системный вызов accept() используется с типами сокетов на основе соединений (SOCK_STREAM, SOCK_SEQPACKET).