Поделиться через


sockaddr

Структура sockaddr зависит от выбранного протокола. За исключением параметра sin*_family , содержимое sockaddr выражается в сетевом порядке байтов.

Функции Winsock, использующие sockaddr, не интерпретируются строго как указатели на структуру sockaddr. Структура интерпретируется по-разному в контексте различных семейств адресов. Единственными требованиями являются то, что первым u_short является семейство адресов, а общий размер буфера памяти в байтах — namelen.

В структуре SOCKADDR_STORAGE также хранятся сведения об адресе сокета, а структура достаточно велика для хранения сведений об адресах IPv4 или IPv6. Использование структуры SOCKADDR_STORAGE способствует независимости семейства протоколов и версий протокола, а также упрощает разработку. Рекомендуется использовать структуру SOCKADDR_STORAGE вместо структуры sockaddr. Структура SOCKADDR_STORAGE поддерживается в Windows Server 2003 и более поздних версиях.

Приведенная ниже структура sockaddr и структуры sockaddr_in используются с IPv4. Другие протоколы используют аналогичные структуры.

struct sockaddr {
        ushort  sa_family;
        char    sa_data[14];
};

struct sockaddr_in {
        short   sin_family;
        u_short sin_port;
        struct  in_addr sin_addr;
        char    sin_zero[8];
};

Приведенные ниже структуры sockaddr_in6 и sockaddr_in6_old используются с IPv6.

struct sockaddr_in6 {
        short   sin6_family;
        u_short sin6_port;
        u_long  sin6_flowinfo;
        struct  in6_addr sin6_addr;
        u_long  sin6_scope_id;
};

typedef struct sockaddr_in6 SOCKADDR_IN6;
typedef struct sockaddr_in6 *PSOCKADDR_IN6;
typedef struct sockaddr_in6 FAR *LPSOCKADDR_IN6;


struct sockaddr_in6_old {
        short   sin6_family;        
        u_short sin6_port;          
        u_long  sin6_flowinfo;      
        struct  in6_addr sin6_addr;  
};

В пакете средств разработки программного обеспечения Microsoft Windows (SDK), выпущенном для Windows Vista и более поздних версий, теги typedef SOCKADDR и SOCKADDR_IN определяются для структур sockaddr и sockaddr_in следующим образом:

typedef struct sockaddr {
#if (_WIN32_WINNT < 0x0600)
    u_short sa_family;
#else 
    ADDRESS_FAMILY sa_family;
#endif //(_WIN32_WINNT < 0x0600)
    CHAR sa_data[14];
} SOCKADDR, *PSOCKADDR, FAR *LPSOCKADDR;


typedef struct sockaddr_in {
#if(_WIN32_WINNT < 0x0600)
    short   sin_family;    
#else //(_WIN32_WINNT < 0x0600)
    ADDRESS_FAMILY sin_family;
#endif //(_WIN32_WINNT < 0x0600)
    USHORT sin_port;
    IN_ADDR sin_addr;
    CHAR sin_zero[8];
} SOCKADDR_IN, *PSOCKADDR_IN;

В windows SDK, выпущенном для Windows Vista и более поздних версий, организация файлов заголовков изменилась, а структуры sockaddr и sockaddr_in определяются в файле заголовка Ws2def.h , а не в файле заголовка Winsock2.h . Файл заголовка Ws2def.h автоматически включается в файл заголовка Winsock2.h . Структура sockaddr_in6 определяется в файле заголовка Ws2ipdef.h , а не в файле заголовка Ws2tcpip.h . Файл заголовка Ws2ipdef.h автоматически включается в файл заголовка Ws2tcpip.h . Файлы заголовков Ws2def.h и Ws2ipdef.h никогда не следует использовать напрямую.

Пример кода

В следующем примере показано использование структуры sockaddr .


// Declare variables
SOCKET ListenSocket;
struct sockaddr_in saServer;
hostent* localHost;
char* localIP;

// Create a listening socket
ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

// Get the local host information
localHost = gethostbyname("");
localIP = inet_ntoa (*(struct in_addr *)*localHost->h_addr_list);

// Set up the sockaddr structure
saServer.sin_family = AF_INET;
saServer.sin_addr.s_addr = inet_addr(localIP);
saServer.sin_port = htons(5150);

// Bind the listening socket using the
// information in the sockaddr structure
bind( ListenSocket,(SOCKADDR*) &saServer, sizeof(saServer) );


См. также:

SOCKADDR_STORAGE