Какие значения протокола совместимы с какими комбинациями домена и типа в socket()?
Я играл с розетками Беркли, а затем я сделал это:
#include <iostream>
#include <sys/socket.h>
#include <cstring>
int main()
{
auto res = socket(AF_INET6, SOCK_STREAM, 58);
if (res < 0) {
std::cout << " Error in creating socket: " << strerror(errno) << '\n';
}
return 0;
}
И вывод был: Error in creating socket: Protocol not supported
, Я выбрал 58, так как хотел попробовать в качестве примера сокет ICMP IPv6 и использовать содержимое /etc/protocols
Я получил это: ipv6-icmp 58 IPv6-ICMP # ICMP for IPv6
, Потом я попробовал 0
на месте 58
в приведенном выше коде, и программа работает нормально. Итак, мои вопросы:
зачем нужен этот третий параметр в вызове socket(), если
уже указаноSOCK_STREAM
(TCP) в качестве протокола по 2-му параметру, т.е. какова причина существования этогоprotocol
(3-й параметр)?Если
protocol
(3-й аргумент) необходимо тогда, что все значения могут принимать
со всеми возможными комбинациямиdomain
(1-й аргумент) иtype
(2-й аргумент)?
Было бы очень полезно, если бы кто-то мог объяснить это примерами, иначе тоже было бы хорошо. Спасибо
1 ответ
- По моему опыту, поле протокола обычно используется только тогда, когда вы используете SOCK_RAW вместо SOCK_DGRAM или SOCK_STREAM.
- значения, которые
protocol
можно принять в зависимости от значений первых двух аргументов. Доступные домены и типы перечислены здесь. На этой же странице сказано следующее оprotocol
поле:
The protocol specifies a particular protocol to be used with the socket. Normally only a single protocol exists to support a particular socket type within a given protocol family, in which case protocol can be specified as 0. However, it is possible that many protocols may exist, in which case a particular protocol must be specified in this manner. The protocol number to use is specific to the “communication domain” in which communication is to take place; see protocols(5). See getprotoent(3) on how to map protocol name strings to protocol numbers.
Вот ссылка на страницу со списком доступных протоколов и связанных с ними значений. Значение протокола ICMP равно 1.
Для настройки ICMP-пакетов вы можете сделать следующее: sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
для настройки пакетов UDP вы бы использовали
sock = socket(AF_INET, SOCK_DGRAM, 0);
или же
sock = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
Также проверьте этот ответ на другой вопрос. Речь идет о нормальных сокетах ICMPv4, но это все равно должно быть полезно, и некоторые части могут быть применимы.