Подтвердить что ты не робот

IPPROTO_IP против IPPROTO_TCP/IPPROTO_UDP

У меня возникли проблемы с поиском документации о том, что такое различие между этими настройками для третьего аргумента socket. Я знаю о TCP и UDP и их различиях, а также о том, что IP - один уровень вверх (вниз?) В стеке... Мой UDP-код, похоже, работает одинаково, устанавливаю ли его значение IPPROTO_IP или IPPROTO_UDP.

4b9b3361

Ответ 1

Документация для socket() в Linux разделяется между различными manpages, включая ip(7), которая указывает, что вы должны использовать 0 или IPPROTO_UDP для UDP и 0 или IPPROTO_TCP для TCP. Когда вы используете 0, который является значением IPPROTO_IP, UDP используется для SOCK_DGRAM, а TCP используется для SOCK_STREAM.

По-моему, чистый способ создания UDP-или-TCP-IPv4-сокета выглядит следующим образом:

int sock_udp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
int sock_tcp = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

Причина в том, что обычно лучше быть явным, чем неявным. В этом конкретном случае использование 0 или хуже IPPROTO_IP для третьего аргумента не принесет вам ничего.

Также представьте, используя протокол, который может выполнять как потоки, так и датаграммы, такие как sctp. Всегда задавая как носок, так и протокол, вы можете избежать какой-либо двусмысленности.

Ответ 2

IPPROTO_IP предназначен для необработанных IP-пакетов. TCP и UDP - это протоколы на основе IP. Если вы открываете сырой IP-сокет, вы несете ответственность за сбор всех IP-байтов самостоятельно. Для открытия сырого IP-сокета может потребоваться привилегированный доступ.

от netinet/in.h:

/*
 * Protocols (RFC 1700)
 */
#define IPPROTO_IP              0               /* dummy for IP */
#define IPPROTO_UDP             17              /* user datagram protocol */
#define IPPROTO_TCP             6               /* tcp */