sockaddr

sockaddr 结构因所选协议而异。 除 sin*_family 参数外,sockaddr 内容以网络字节顺序表示。

使用 sockaddr 的 Winsock 函数不会严格解释为指向 sockaddr 结构的指针。 结构在不同的地址系列上下文中解释不同。 唯一的要求是,第一 个u_short 是地址系列,内存缓冲区的总大小(以字节为单位)是 namelen

SOCKADDR_STORAGE结构还存储套接字地址信息,结构足够大,可以存储 IPv4 或 IPv6 地址信息。 使用 SOCKADDR_STORAGE 结构可促进协议系列和协议版本独立性,并简化开发。 建议使用 SOCKADDR_STORAGE 结构代替 sockaddr 结构。 Windows Server 2003 及更高版本支持 SOCKADDR_STORAGE 结构。

下面的 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;  
};

在为 Windows Vista 及更高版本发布的 Microsoft Windows 软件开发工具包 (SDK) 上, SOCKADDRSOCKADDR_IN typedef 标记为 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 Vista 及更高版本发布的 Windows SDK 上,头文件的组织已更改,sockaddr 和 sockaddr_in 结构在 Ws2def.h 头文件中定义,而不是 在 Winsock2.h 头文件中定义。 Ws2def.h 头文件自动包含在 Winsock2.h 头文件中。 sockaddr_in6结构在 Ws2ipdef.h 头文件中定义,而不是 在 Ws2tcpip.h 头文件中定义。 Ws2ipdef.h 头文件自动包含在 Ws2tcpip.h 头文件中。 不应直接使用 Ws2def.hWs2ipdef.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