2009-12-23 2 views
15

Когда требуется IPPROTO_UDP?, когда требуется IPPROTO_UDP?

Есть ли когда-нибудь случай, когда UDP не протокол по умолчанию для SOCK_DGRAM? (Реальные случаи, а не гипотетический «может быть», пожалуйста ")

т.е. каковы ситуации, когда следующие две строки будут не производят одинаковое поведение

if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1) 
if ((s=socket(AF_INET, SOCK_DGRAM, 0))==-1) 

ответ

12

Учитывая эти заявления:

tcp_socket = socket(AF_INET, SOCK_STREAM, 0); 
udp_socket = socket(AF_INET, SOCK_DGRAM, 0); 
raw_socket = socket(AF_INET, SOCK_RAW, protocol); 

страница ip(7) руководство в Linux говорит:

Единственными допустимыми значениями для протокола являются 0 и IPPROTO_TCP для сокетов TCP и 0 и IPPROTO_UDP для сокетов UDP. Для SOCK_RAW вы можете указать действительный IP-протокол IANA, определенный в RFC 1700 присвоенных номеров.

Эти две строки в ваших вопросах всегда будут давать одинаковый результат.

+0

Я думаю, что использование 'IPPROTO_UDP' intsead of zero - это не тот же результат, что и у вас есть сокет, который требует, чтобы вы заполнили все заголовки. – WilliamKF

14

Некоторые операционные системы (например, ядро ​​Linux после версии 2.6.20) поддерживают второй протокол для SOCK_DGRAM, называемый UDP-Lite. Если поддерживается вашей системой, она будет включена, предоставив IPPROTO_UDPLITE в качестве третьего аргумента вызова socket().

Он отличается от обычного UDP, позволяя применять контрольные суммы только к части дейтаграммы. (Обычно проверка контрольных сумм UDP - это попытка «ничего или ничего».) Таким образом, протокол может быть более устойчивым к сбоям контрольной суммы из-за фрагментированной передачи, в случае, если некоторые фрагменты вне контрольной суммы могут быть потеряны при транзите. До тех пор, пока фрагменты, покрывающие контрольную сумму, были успешно получены, большая часть дейтаграммы по возможности будет доставляться в приложение.

Для обратной совместимости с существующим кодом я подозреваю (но не могу гарантировать), что сокет вызова (AF_INET, SOCK_DGRAM, 0) будет по-прежнему использоваться по умолчанию для обычного UDP, даже в системах, которые дополнительно поддерживают UDP-Lite.

Смежные вопросы