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 標頭檔。 Winsock2.h標頭檔會自動包含Ws2def.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