說明 前一篇
所有的WinSock函數都使用sockaddr結構來傳遞地址信息,該結構定義如下:
struct sockaddr {
u_short sa_family; /* address family */
char sa_data[14];/* up to 14 bytes of direct address */
};
需要注意的是,socket并不只是為TCP服務的,它支持多種協議,而各種協議的地址格式又大相徑庭。因此,我們在socket相關的API中不
可能用同樣的地址結構來描述地址信息,這里的sockaddr只是一個占位符的角色,我們在實際編程中必須替換乘合適的地址類型。
對于TCP/IP族,我們需要用的結構類型是sockaddr_in,該結構定義如下:
struct sockaddr_in {
short sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
其中in_addr定義為:
struct in_addr {
union {
struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;
struct { u_short s_w1,s_w2; } S_un_w;
u_long S_addr;
} S_un;
#define s_addr S_un.S_addr
/* can be used for most tcp & ip code */
#define s_host S_un.S_un_b.s_b2
/* host on imp */
#define s_net S_un.S_un_b.s_b1
/* network */
#define s_imp S_un.S_un_w.s_w2
/* imp */
#define s_impno S_un.S_un_b.s_b4
/* imp # */
#define s_lh S_un.S_un_b.s_b3
/* logical host */
};
需要注意的是,這個sockaddr_in結構和sockaddr結構尺寸一樣,我不清楚這是巧合還是必須遵守的一個準則。在我看來,這個結構不一樣也是可以的。
我不打算一一介紹各個宏和域的含義,因為絕大多數人都不會記住這個。我只想簡要介紹一下如何初始化這個地址信息
- sa_family:這個域描述了地址族信息。對于TCP/IP,這個值必須設置為AF_INET。有興趣的朋友可以到WinSock.H中找找看它還支持哪些值。
- sin_port:端口號,對于我們提供的端口號,必須用htons轉換一下再賦值,方法是:
addr.sin_port = htons(port);
- sin_addr:地址,這里應該是IP地址。我們可以用inet_addr函數從點分式IP地址轉換得到這個IP地址,方法是:
addr.sin_addr.s_addr = inet_addr("100.101.102.103");
注意:這里使用了宏s_addr,該宏的定義請參考上文。
- sin_zero:填充信息,必須設置為0。初學編程的人往往忘記初始化這個域,根據我的經驗,這會導致函數調用失敗。
由于API中都使用sockaddr結構,因此在使用時必須進行強制類型轉換,并提供結構尺寸信息。下面就是accept函數調用時的例子:
sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sa_family = AF_INET;
int size = sizeof(addr);
SOCKET sd = accept(serversd, (sockaddr*)&addr, &size);
posted on 2008-07-03 15:16
SIMONE 閱讀(423)
評論(0) 編輯 收藏 所屬分類:
C++