Winsock使用前需要加载响应的Winsock库,例如:
#include <winsock.h>
#pragma comment (lib, "Ws2_32.lib")
Winsock库在使用前需要用WSAStartup()初始化:
WSADATA wd;
WSAStartup(MAKEWORD(2,2), &wd);
第一个参数用于指定准备加载的Winsock库的版本。高位字节指定所需要的Winsock库的副版本,而低位字节则是主版本。然后,可用宏MAKEWORD(x, y)(其中,x是低位字节, y是高位字节)方便地获得输入WORD的正确值。
第二个参数被WSAStartup用其加载的库版本有关的信息填充。其中wVersion成员是当前使用版本,wHighVersion成员是现有Winsock库的最高版本。
WSADATA wd;
WSAStartup(MAKEWORD(1,1), &wd);
WORD now = wd.wVersion;
WORD max = wd.wHighVersion;
cout<<(now&0x00FF)<<"."<<((now>>8)&0x00FF)<<endl; //使用版本1.1
cout<<(max&0x00FF)<<"."<<((max>>8)&0x00FF)<<endl; //最高版本2.2
地址信息结构体:
struct sockaddr_in {
short sin_family; //地址族,一般为AF_INET
u_short sin_port; //端口(16位)
struct in_addr sin_addr; //IP
char sin_zero[8]; //reserve
};
赋值如下:
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(5000);
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
htons()把主机字节序转换成16位网络字节序,用于给端口赋值。
ntohs()是其逆运算。
inet_addr()把IP字符串转换成IP结构,用于给IP地址赋值。
inet_ntoa()是其逆运算。
主机名与IP地址
hostent* gethostbyname( //通过给定的主机名(可以使IP字符串),获得主机信息。
const char* name
);
hostent* gethostbyaddr( //通过给定的IP(网络字节顺序),获得主机信息。
const char* addr, //IP(网络字节顺序)
int len, //IP地址长度(字节)
int type //IP地址类型(PF_INET or PF_INET6)
);
struct hostent {
char FAR * h_name; //官方主机名
char FAR * FAR * h_aliases; //主机别名list
short h_addrtype; //主机地址类型(PF_INET or PF_INET6)
short h_length; //主机地址长度
char FAR * FAR * h_addr_list; //主机IP地址list(网络字节顺序)
#define h_addr h_addr_list[0] //主机第一个IP地址
#include <iostream>
#include <winsock2.h>
#pragma comment (lib, "Ws2_32.lib")
using namespace std;
int main()
{
WSADATA wd;
::WSAStartup(MAKEWORD(2,2), &wd);
hostent* ht = gethostbyname("127.0.0.1");
if(NULL == ht)
{
cout<<"error"<<endl;
::WSACleanup();
return 1;
}
cout<<ht->h_name<<endl; //输出主机名
cout<<ht->h_addrtype<<endl; //输出主机地址类型
char** p = ht->h_aliases;
for(;*p!=NULL;p++) //输出主机别名
printf("aliases: %s\n", *p);
p = ht->h_addr_list;
for(;*p!=NULL;p++) //输出主机IP地址
printf("address: %s\n\n", inet_ntoa(*(in_addr*)(*p) ) );
hostent* htt = gethostbyaddr(ht->h_addr, 4, PF_INET); //根据上面获得的主机IP获得主机信息
if(NULL == htt)
{
cout<<"error"<<endl;
::WSACleanup();
return 1;
}
cout<<htt->h_name<<endl; //输出主机名
cout<<htt->h_addrtype<<endl;//输出主机地址类型
p = htt->h_aliases;
for(;*p!=NULL;p++) //输出主机别名
printf("aliases: %s\n", *p);
p = htt->h_addr_list;
for(;*p!=NULL;p++) //输出主机IP地址
printf("address: %s\n", inet_ntoa(*(in_addr*)(*p) ) );
::WSACleanup();
return 0;
}