tcp/ip協議中,專門保留了三個IP地址地區作為私人地址,其位址範圍如下:
10.0.0.0/8:10.0.0.0~10.255.255.255
172.16.0.0/12:172.16.0.0~172.31.255.255
192.168.0.0/16:192.168.0.0~192.168.255.255使用保留地址的網路只能在內部進行通訊,而不能與其他網路互連。如果要與外部通訊,那麼必須通過網關與外部通訊,這裡使用了NAT, NAPT技術就是用來保證通訊的代理機制。 另外,一些寬頻電訊廠商儘管也使用了非私人地址分配給使用者使用,但是由於路由設定的原因,Internet上的其他使用者並不能訪問到這些ip。上面2部分IP都可稱為內網IP,下面這部分IP不列入本次討論範圍。 如果自己機器上網路介面的ip地址落在上述保留地址的範圍內,則可以肯定自己處於內網模式下。NAT要求整個服務的串連是從內網向外網主動發起的,而外網的使用者無法直接(主動)向內網的服務發起串連請求,除非在NAT的(所有)網關上針對服務的連接埠作了連接埠映射。NAT方式要求最外圍的網關至少有一個公網的IP,可以訪問顯IP的外部伺服器如:http://ipid.shat.net/ 擷取到外部IP,將這個IP與自己機器上網路介面的ip比較,即可知道自己的ip是不是內網IP。 判斷自己IP類型,可使用下面三種任意一種方法:1) 在windos命令台程式下,用ipconfig。Eg: 下面內網IP是192.168.0.1,外網IP是125.34.47.25,因此是網關。C:/Documents and Settings/user>ipconfig Windows IP ConfigurationEthernet adapter 本地串連: Connection-specific DNS Suffix . : IP Address. . . . . . . . . . . . : 192.168.0.1 Subnet Mask . . . . . . . . . . . : 255.255.255.0 Default Gateway . . . . . . . . . : 192.168.0.1 Ethernet adapter {6C8AEC26-0EC3-40FE-812E-A46778ECA752}: Media State . . . . . . . . . . . : Media disconnected PPP adapter 寬頻撥號: Connection-specific DNS Suffix . : IP Address. . . . . . . . . . . . : 125.34.47.25 Subnet Mask . . . . . . . . . . . : 255.255.255.255 Default Gateway . . . . . . . . . : 125.34.47.25 2) 用tracert來判斷IP類型如果每一個hops不是內網IP,那麼自己就是外網IP了,反之,如果自己是內網IP,那麼每一個hops顯示的就是網關的內網IP,下面的例子顯然說明是外網IP了。C:/Documents and Settings/user>tracert www.baidu.com Tracing route to www.a.shifen.com [202.108.22.5]over a maximum of 30 hops: 1 15 ms 16 ms 14 ms 125.34.40.1 2 14 ms * * 61.148.8.9 3 26 ms 72 ms 40 ms xd-22-5-a8.bta.net.cn [202.108.22.5] Trace complete. 3)編程實現擷取到本機所有的IP地址清單,對IP列表進行分析:1) 如果列表中只有區域網路IP,那麼說明是在內網;2) 如果列表中有區域網路IP,也有公網IP,那麼說明是網關;3) 如果列表中只有公網IP,那麼說明是獨立IP。//此處不考慮其它平台,在inet架構下測試, 輸入的ip為主機位元組順序// 0xa -- "10.0.0.0">>24; 0xc0a8--"192.168.0.0.">>16; 0x2b0--"127.17.0.1">>22int isInnerIP( uint32_t a_ip ){ int bValid = -1; if( (a_ip>>24 == 0xa) || (a_ip>>16 == 0xc0a8) || (a_ip>>22 == 0x2b0) ) { bValid = 0; } return bValid;}int isInnerIP( char* a_strip ){ return 0;}
IP相關的應用//擷取到本機所有的IP地址清單,並分別用字串與整形形式來顯示int getHostIP() //return int{ struct sockaddr_in localAddr, destAddr; struct hostent* h; char temp[128]; int nRect = gethostname(temp, 128); printf("ipaddr src3 is: %s/n", temp); if(nRect !=0) { printf("error"); } h = gethostbyname(temp); if(h) { for(int nAdapter=0; h->h_addr_list[nAdapter]; nAdapter++) { memcpy(&destAddr.sin_addr.s_addr, h->h_addr_list[nAdapter], h->h_length); // 輸出機器的IP地址. printf("Address string: %s/n", inet_ntoa(destAddr.sin_addr)); // 顯示地址串 printf("Address int: %d/n", destAddr.sin_addr.s_addr); // 轉化為整形數字 } } return 0;} //檢查字串IP是否合法int isCheckTrue(char* strip){ int value; for( int i = 0; i < strlen(strip); i++) { // let's check if all entered char in entered // IP address are digits if(strip[i] == '.') continue; if(isdigit(strip[i]) == 0) { return -1; } } return 0;}//將字串IP轉化為整形IPint str2intIP(char* strip) //return int ip{ int intIP; if(!(intIP = inet_addr(strip))) { perror("inet_addr failed./n"); return -1; } return intIP;}