windows网络编程常用

来源:互联网 发布:手机贴纸淘宝 编辑:程序博客网 时间:2024/04/30 19:29

主机的字节序与网络字节序

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

void initWinSock()
{
    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);
}

0 0
原创粉丝点击