Почему socketpair() допускает тип SOCK_DGRAM?

Недавно я узнал о программировании сокетов Linux, в основном из этого сайт.

На сайте сказано, что использование комбинации домен/тип PF_LOCAL/SOCK_DGRAM...

Предоставляет услуги дейтаграмм на локальном хосте. Обратите внимание, что эта служба без установления соединения, но надежна, за возможным исключением того, что пакеты могут быть потеряны, если буферы ядра будут исчерпаны.

Тогда мой вопрос: почему socketpair(int domain, int type, int protocol, int sv[2]) разрешает эту комбинацию, когда, согласно его справочной странице...

Вызов socketpair() создает безымянную пару подключенных сокетов в указанном домене указанного типа...

Нет ли здесь противоречия?

Я думал, что SOCK_DGRAM в доменах PF_LOCAL и PF_INET подразумевает UDP, который является протоколом без установления соединения, поэтому я не могу примирить кажущийся конфликт с заявлением socketpair() о создании подключенных сокетов.


person StoneThrow    schedule 01.06.2017    source источник


Ответы (1)


Сокеты дейтаграмм имеют «псевдосоединения». Протокол на самом деле не имеет соединений, но вы все равно можете вызвать connect(). Это связывает удаленный адрес и порт с сокетом, а затем получает только пакеты, которые приходят из этого источника, а не все пакеты, пунктом назначения которых является адрес/порт, к которому привязан сокет, и вы можете использовать send(), а не sendto() для отправить обратно на этот удаленный адрес.

Примером, где это может быть использовано, является протокол TFTP. Сначала сервер прослушивает входящие запросы на хорошо известном порту. После начала передачи используется другой порт, и отправитель и получатель могут использовать connect(), чтобы связать сокет с этой парой портов. Затем они могут просто отправлять и получать через этот новый сокет, чтобы участвовать в передаче.

Точно так же, если вы используете socketpair() с сокетами дейтаграмм, это создает псевдосоединение между двумя сокетами.

person Barmar    schedule 01.06.2017
comment
Использование connect() в сокете дейтаграммы также позволяет использовать recv() и send() в этом сокете вместо необходимости использования recvfrom() и sendto(). - person Remy Lebeau; 02.06.2017
comment
@RemyLebeau Я думаю, вы можете использовать recv() в неподключенном сокете, вы просто не будете знать, откуда он взялся. Но вы правы насчет send(). - person Barmar; 02.06.2017