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