Socket(一) ---- 基础知识
Winsock使用前需要加载响应的Winsock库,例如:
Winsock库在使用前需要用WSAStartup()初始化:
第二个参数被WSAStartup用其加载的库版本有关的信息填充。其中wVersion成员是当前使用版本,wHighVersion成员是现有Winsock库的最高版本。
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
<
winsock.h
>
#pragma comment (lib, " Ws2_32.lib " )
#pragma comment (lib, " Ws2_32.lib " )
Winsock库在使用前需要用WSAStartup()初始化:
WSADATA wd;
WSAStartup(MAKEWORD( 2 , 2 ), & wd);
第一个参数用于指定准备加载的Winsock库的版本。高位字节指定所需要的Winsock库的副版本,而低位字节则是主版本。然后,可用宏MAKEWORD(x, y)(其中,x是低位字节, y是高位字节)方便地获得输入WORD的正确值。
WSAStartup(MAKEWORD( 2 , 2 ), & wd);
第二个参数被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
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
} ;
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 " );
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;
}
#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;
}