主机的字节序与网络字节序
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
h---host 本地主机,to 就是to 了,n ---net 网络的意思,l 是 unsigned long,"s"表示short,"l"表示long
in_addr与字符串的转换
typedef struct in_addr {
union {
struct { UCHAR s_b1,s_b2,s_b3,s_b4; } S_un_b;
struct { USHORT s_w1,s_w2; } S_un_w;
ULONG 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
} IN_ADDR, *PIN_ADDR, FAR *LPIN_ADDR;
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;
unsigned long WSAAPI inet_addr(__in IN const char FAR * cp );
char FAR *WSAAPI inet_ntoa( IN struct in_addr in);
inet_addr函数需要一个字符串作为其参数,该字符串指定了以点分十进制格式表示的IP地址(例如:192.168.0.16)。而且inet_addr函数会返回一个适合分配给S_addr的u_long类型的数值。
Inet_ntoa函数会完成相反的转换,它接受一个in_addr结构体类型的参数并返回一个以点分十进制格式表示的IP地址字符串。
获取本地IP
引入ws2_32.lib
{
static bool wsInit = false;
if (! wsInit)
{
WORD wVersionRequested = MAKEWORD( 2, 0);
WSADATA wsaData;
if (0 == WSAStartup(wVersionRequested, &wsaData))
{
wsInit = true;
}
}
}
string GetLocalIP()
{
string strLocalIP;
//Socket初始化部分
initWinSock();
//通过本机主机名.
char host_name[256];
gethostname(host_name,sizeof(host_name));
struct hostent *hp;
struct in_addr sa;
char *buf;
hp = gethostbyname(host_name);
if (hp != NULL)
{
//循环获取本地主机名
for (int i = 0; i <= 0/*hp->h_addr_list[i]*/; i++)
{
memcpy (&sa, hp->h_addr_list[i],hp->h_length);
buf = inet_ntoa(sa);
}
}
strLocalIP = buf;
return strLocalIP;
}
获取子网掩码
再引入IPHLPAPI.lib
std::string GetMaskFromIp(const std::string &ip)
{
std::string ret;
PIP_ADAPTER_INFO pAdapterInfo;
PIP_ADAPTER_INFO pAdapter = NULL;
ULONG ulOutBufLen = sizeof (IP_ADAPTER_INFO);
pAdapterInfo = (IP_ADAPTER_INFO *)malloc(sizeof (IP_ADAPTER_INFO));
if (ERROR_BUFFER_OVERFLOW == GetAdaptersInfo(pAdapterInfo, &ulOutBufLen))
{
free(pAdapterInfo);
pAdapterInfo = (IP_ADAPTER_INFO *) malloc(ulOutBufLen);
}
if (NO_ERROR == GetAdaptersInfo(pAdapterInfo, &ulOutBufLen))
{
pAdapter = pAdapterInfo;
while (pAdapter)
{
if (ip == pAdapter->IpAddressList.IpAddress.String)
{
ret = pAdapter->IpAddressList.IpMask.String;
break;
} // 在这里循环可以获取所有网卡信息
pAdapter = pAdapter->Next;
}
}
if (pAdapterInfo)
{
free(pAdapterInfo);
}
return ret;
}
获取广播地址
/*
算法:
1. 子网掩码与IP地址进行位与运算,得处网络地址
2. 网络地址 | (~子网掩码),得出广播地址
*/
string GetBroadcastIp(string strIP,string strNetMask)
{
in_addr broadcast;
broadcast.S_un.S_addr = ( inet_addr(strIP.c_str()) & inet_addr(strNetMask.c_str())) | (~inet_addr(strNetMask.c_str()));
return inet_ntoa(broadcast);
}