Программирование на C - Понимание bind () - PullRequest
4 голосов
/ 25 июля 2011

У меня проблемы с пониманием функции bind () в отношении доменных сокетов Unix.

address.sun_family = AF_UNIX;
addrlen = sizeof(address.sun_family) + strlen(SOCK_PATH);
.
.
.
bind(socket_fd, (struct sockaddr *) &address, addrlen) != 0) 

Как я понимаю в настоящее время, для этого используется socket_fd (расположенный в пространстве имен процессов), который был создан с помощьюsocket () и «применяет» адресную информацию, содержащуюся в адресе к сокету.По сути, создавая его так, чтобы другие процессы могли его использовать .... Я думаю, что это правильно.

Что я не понимаю, так это необходимость аргумента addrlen.Это длина структуры адреса без начальных / конечных нулевых байтов.Правильный?Нужен ли этот аргумент, чтобы указать bind (), сколько байтов считать вне адреса ???

Спасибо за понимание!

Ответы [ 3 ]

3 голосов
/ 25 июля 2011

Проще говоря, bind говорит системе: okay, from now on, any packet with destination {address->sun_addr} should be forwarded to my socket_fd, so I can read them.

Аргумент addrlen указывает размер структуры, потому что различные типы структуры (разных размеров)) можно пройти.Например, struct sockaddr_un*, struct sockaddr_in*.Вместо этого передается «общая» структура, struct sockaddr*, поэтому bind не знает, каков тип real вашей структуры.Вот почему вы должны передать длину.

PS: я уверен, что вы имели в виду адресное пространство процесса , а не пространство имен процесса .

1 голос
/ 25 июля 2011

Не уверен, почему ваш адрлен настроен так, правильный / обычный метод:

   memset(&addr, 0, sizeof(struct sockaddr_un));
                        /* Clear structure */
   addr.sun_family = AF_UNIX;
   strncpy(addr.sun_path, MY_SOCK_PATH,
            sizeof(addr.sun_path) - 1);

   if (bind(sfd, (struct sockaddr *) &addr,
            sizeof(struct sockaddr_un)) == -1) {
        perror("bind");
        exit(EXIT_FAILURE);
   }

обратите внимание на использование sizeof (), strlen / addrlen не ожидается

0 голосов
/ 23 декабря 2013

Я также все еще учусь, вот что привело меня сюда, так что, возможно, объяснение моего понимания поможет мне также учиться, так что будьте утомлены, я могу быть очень неправ, или я могу быть в правильном направлении ...

Вам это нужно, потому что адреса IPv4 и IPv6 имеют разную длину, как и адреса разных протоколов, я бы предположил, что не все протоколы, такие как Apple Talk или протоколы Ham Radio, используют адреса, похожие на адреса в стиле IPv4, которые представляют собой набор из 4 байты, октеты, я думаю, они называются, разделенные символом ".".

Поэтому, когда вы вызываете «sizeof (struct sockaddr_in)», вы передаете «int», которое представляет собой количество байтов, из которых состоит sockaddr_in, что будет отличаться от «sizeof (struct sockaddr_in6)» для sizeof (struct sockaddr_un) , sockaddr_in предназначен для inet или IPv4, * _in6 - для inet6 или IPv6, а * _un - для доменных сокетов Unix. Я считаю, что адреса сокетов доменов Unix - это пути к файлам, которые можно использовать только для локального взаимодействия процессов. Так что, во-первых, функция / метод должна знать, где находится файл сокета, например / home / user / Pictures / socket, чтобы он мог связать его с локальным портом, следовательно, с бизнесом strncopy и sun_path. Это может также относиться к сокетам inet / 6, winsocks могут отличаться. (Изучение C / C ++ в Windows было самым близким к самоубийству, которое я когда-либо имел).

int, который передается через "sizeof (struct sockaddr_un)", может использоваться для определения режима выполнения в фактическом коде реализации. если arg [2] = N сделать это, иначе, если arg [2] = M сделать это ??? Может быть ...

Если вы прочитаете руководство по сокетам, вы увидите, что в примере используется "sizeof ()", а не addrlen.

Примечание: При достижении размера в байтах адресной структуры вашего протокола, не имеет значения, содержит ли используемая вами структура действительно полезные данные, вам просто нужен ее размер, поэтому структура создается в параметре с помощью "sizeof ()" во вновь созданной структуре возвращает int, которое вам нужно, и именно это используется в качестве аргумента для 3-го параметра.

...