Временно недоступен
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
1

Struct sockaddr vs. struct sockaddr_in

28.02.2010, 20:53. Показов 16999. Ответов 7

Вопрос,связанный с переносимостью кода на другие платформы.
Читаю эту книжку http://beej.us/guide/bgnet/out... bgnet.html и там написано:
C
1
2
3
4
struct sockaddr {
    unsigned short    sa_family;    // address family, AF_xxx
    char              sa_data[14];  // 14 bytes of protocol address
};
... указатель на struct sockaddr_in может быть приведён к указателю на struct sockaddr и обратно. И несмотря на то,что connect() принимает struct sockaddr*, вы можете использовать struct sockaddr_in* и привести его к нужному типу в последний момент!

C
1
2
3
4
5
6
7
8
// (IPv4 only--see struct sockaddr_in6 for IPv6)
 
struct sockaddr_in {
    short int          sin_family;  // Address family, AF_INET
    unsigned short int sin_port;    // Port number
    struct in_addr     sin_addr;    // Internet address
    unsigned char      sin_zero[8]; // Same size as struct sockaddr
};
Меня смущает размер этих двух структур.Разве он всегда,на всех машинах одинаков?Гарантировано,что char = 1 байту,а как быть с остальными int-ами?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
28.02.2010, 20:53
Ответы с готовыми решениями:

typedef struct Foo или struct Foo
В чём разница между: typedef struct { int a; }Foo; и struct Foo { int a; }

typedef struct X{X* pX;}X;
Собственно сабж: typedef struct X{ X* ptrX; }X; Когда происходит объявление ptrX тип...

Typedef struct
Добрый день!! пытаюсь разобраться со структурами,вроде бы как все понятно кроме одного.Ключевое...

Struct somestruct ;
Что значит ? Если в файле такая строчка : struct somestruct ; Обявление структуры?

7
2825 / 1634 / 252
Регистрация: 03.12.2007
Сообщений: 4,222
28.02.2010, 21:27 2
Просто int'а тут нет, short в реале вроде везде 2 байта, а в теории даже размер char'а не гарантирован.
1
1259 / 797 / 108
Регистрация: 16.09.2009
Сообщений: 2,010
28.02.2010, 22:02 3
От машинно зависимости можно избавится с помощью typedef.
Это мнение я разделяю, зачем нужен typedef: гугл в помощь.
1
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
11047 / 6994 / 1656
Регистрация: 25.07.2009
Сообщений: 12,764
28.02.2010, 22:05 4
Цитата Сообщение от #pragma Посмотреть сообщение
Меня смущает размер этих двух структур.Разве он всегда,на всех машинах одинаков?
Не, размер структуры в функцию дополнительным параметром вместе с указателем на структуру передаётся. К примеру:
Код
int bind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen);
int  connect(int  sockfd,  const  struct sockaddr *serv_addr, socklen_t addrlen);
etc...
1
Evg
Эксперт CАвтор FAQ
21204 / 8220 / 633
Регистрация: 30.03.2009
Сообщений: 22,542
Записей в блоге: 30
01.03.2010, 14:29 5
Важно лишь то, что по указателю на любой из этих типов мы можем читать первое поле структуры, которое в обоих случаях будет по нулевому смещению от указателя. В этом полу по сути закодирована информация о том, указатель какого типа структура на самом деле подан

Т.е. функции connect ты передаёшь указатель на sockaddr (грубо говоря, можно передавать и указатель на void, принципиально ничего не изменится). Далее читается первое поле структуры (p->sa_family). Если значение в нём равно AF_INET, то этот указатель приводится к указателю на sockaddr_in. При этом приведение указателя - чисто техническая формальность для компилятора, адрес в указателе не меняется. Если в этом поле записано значение AF_UNIX, то далее указатель приводится к указателю sockaddr_un

По сути этонекий способ моделирования наследования классов на Си

> Меня смущает размер этих двух структур.Разве он всегда,на всех машинах одинаков?
> Гарантировано,что char = 1 байту,а как быть с остальными int-ами?

На разных платформах поле sa_data описано по разному (каждая платформа "знает" о том, сколько байт занимают структуры sockaddr_in и sockaddr_un). Пользователь напрямую с этим полем работать не должен. Это поле нужно для того, чтобы можно было взять размер от этой структуры (чтобы была возможностьработать не только с указателем, но и копировать объект целиком, не разбираясь, какго он на самом деле типа)
2
Временно недоступен
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
02.03.2010, 07:00  [ТС] 6
Далее читается первое поле структуры (p->sa_family). Если значение в нём равно AF_INET, то этот указатель приводится к указателю на sockaddr_in. При этом приведение указателя - чисто техническая формальность для компилятора, адрес в указателе не меняется.
Значит ли это,что явно приводить к определённой структуре не нужно,передавая структуру в функцию,и это неявно делает компилятор?
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
11047 / 6994 / 1656
Регистрация: 25.07.2009
Сообщений: 12,764
02.03.2010, 09:08 7
Цитата Сообщение от #pragma Посмотреть сообщение
Значит ли это,что явно приводить к определённой структуре не нужно,передавая структуру в функцию,и это неявно делает компилятор?
Функции сокетов определяются таким образом, что их аргументом является указатель на общую структуру адреса сокета, как показано в прототипе функции bind (ANSI C):
C
1
int bind(int, struct sockaddr *, socklen_t);
При этом требуется, чтобы для любых вызовов этих функций указатель на структуру адреса сокета, специфичную для протокола, был преобразован в указатель на универсальную структуру адреса сокета. Например:
C
1
2
3
struct sockaddr_in serv; /* структура адреса сокета IPv4 */
/* заполняем serv{} */
bind(sockfd, (struct sockaddr *) &serv, sizeof(serv));
...
С точки зрения разработчика приложений, универсальная структура адреса сокета используется только для преобразования указателей на структуры адресов конкретных протоколов.
"UNIX разработка сетевых приложений" У. Р. Стивенс, Б. Фендер, Э. М. Рудофф
2
Evg
Эксперт CАвтор FAQ
21204 / 8220 / 633
Регистрация: 30.03.2009
Сообщений: 22,542
Записей в блоге: 30
02.03.2010, 09:51 8
Цитата Сообщение от #pragma Посмотреть сообщение
Значит ли это,что явно приводить к определённой структуре не нужно,передавая структуру в функцию,и это неявно делает компилятор?
С точки зрения передачи параметра (и не только передачи) указатель является всего лишь адресом в памяти и совершено пофигу, какой он имеет тип. Другое дело, что современные компиляторы обычно выдают ошибки или предупреждения в тех местах, где идёт неявное преобразование указателей на разные типы структур, потому как это может быть потенциальной ошибкой программиста.
2
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
02.03.2010, 09:51

State struct
Добрый день. Начинающий в си, не написал ничего большого и интересного. У меня возник вопрос,...

Undefined symbol 'struct'
#include <stdio.h> #include <stdlib.h> struct Str { char *num1; char *num2; char *num3;...

Описать тип struct
Описать тип struct Rectangle, задающий на плоскости замкнутый прямоугольник со сторонами,...

Сокращение дроби (struct)
Здравствуйте, нужно, чтобы выводился НОД и сокращенная дробь и дробь определялась через структуру....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.