IP地址的三种表示格式 及 在Socket编程中的应用
關(guān)于windows中的INADDR_ANY這個(gè)宏
頭文件winsock.h中定義#define INADDR_ANY????????????? (u_long)0x00000000
它是用于多IP機(jī)器上???
? 比如你的機(jī)器有三個(gè)ip???
? 192.168.1.1???
? 202.202.202.202???
? 61.1.2.3???
????
? 如果你serv.sin_addr.s_addr=inet_addr("192.168.1.1");???
????
? 然后監(jiān)聽100端口???
????
? 這時(shí)其他機(jī)器只有connect?? 192.168.1.1:100才能成功。???
? connect?? 202.202.202.202:100和connect?? 61.1.2.3:100都會(huì)失敗。???
????
? 如果serv.sin_addr.s_addr = htonl(INADDR_ANY);?? 的話,無(wú)論連接哪個(gè)ip都可以連上的。
?(也可以serv.sin_addr.s_addr = 0;? )
?
獲取到本機(jī)的IP地址,可以通過(guò) getsockname函數(shù)。
===========================================================================================
?
使用TCP/IP協(xié)議進(jìn)行網(wǎng)絡(luò)應(yīng)用開發(fā)的朋友首先要面對(duì)的就是對(duì)IP地址信息的處理。IP地址其實(shí)有三種不同的表示格式:
? ? ???1)Ascii(網(wǎng)絡(luò)點(diǎn)分字符串)-
? ? ? ?2) 網(wǎng)絡(luò)地址(32位無(wú)符號(hào)整形,網(wǎng)絡(luò)字節(jié)序,大頭)
? ? ? ?3)主機(jī)地址 (主機(jī)字節(jié)序) ?
? ? ? ?IP地址是IP網(wǎng)絡(luò)中數(shù)據(jù)傳輸?shù)囊罁?jù),它標(biāo)識(shí)了IP網(wǎng)絡(luò)中的一個(gè)連接,一臺(tái)主機(jī)可以有多個(gè)IP地址,IP分組中的IP地址在網(wǎng)絡(luò)傳輸中將保持不變。下面具體介紹IP地址的三種不同表示格式。一、點(diǎn)分10進(jìn)制表示格式 ??
? ? ? ? 這是我們最常見的表示格式,比如某機(jī)的IP地址可能為“202.101.105.66”。事實(shí)上,對(duì)于Ipv4(IP版本)來(lái)說(shuō),IP地址是由一個(gè)32位的二進(jìn)制數(shù)所構(gòu)成,但這樣一串?dāng)?shù)字序列無(wú)疑是十分冗長(zhǎng)并且難以閱讀和記憶的。為了方便人們的記憶和使用,就將這串?dāng)?shù)字序列分成4組,每組8位,并改為用 10進(jìn)制數(shù)進(jìn)行表示,最后用小原點(diǎn)隔開,于是就演變成了“點(diǎn)分10進(jìn)制表示格式”。 ??
? ? ? ?來(lái)看看剛才那個(gè)IP地址的具體轉(zhuǎn)化過(guò)程: ??
? ? ?? ?IP實(shí)際地址: 11001010011001010110100101000010 ??
? ? ?? 分成4組后: ? ? 11001010 ? 01100101 ? 01101001 ? 01000010 ??
? ? ?? 十進(jìn)制表示: ?? 202 ? ? ? ? ? ? ? ? ?101 ? ? ? ? ? ? ?105 ? ? ? ? ? ? ? ?66 ??
? ? ??點(diǎn)分表示: ? ? ??202.101.105.66 ??
二、網(wǎng)絡(luò)字節(jié)順序格式(NBO,Network ? Byte ? Order) ?
? ? ? ?網(wǎng)絡(luò)字節(jié)順序格式和主機(jī)字節(jié)順序格式一樣,都只在進(jìn)行網(wǎng)絡(luò)開發(fā)中才會(huì)遇到。因此,在下面的介紹中,我假設(shè)讀者對(duì)Socket編程知識(shí)有一定的基礎(chǔ)。 ??
? ? ? 在網(wǎng)絡(luò)傳輸中,TCP/IP協(xié)議在保存IP地址這個(gè)32位二進(jìn)制數(shù)時(shí), 協(xié)議規(guī)定采用在低位存儲(chǔ)地址中包含數(shù)據(jù)的高位字節(jié)的存儲(chǔ)順序(大頭) ,這種順序格式就被稱為 網(wǎng)絡(luò)字節(jié)順序格式 。在實(shí)際網(wǎng)絡(luò)傳輸時(shí),數(shù)據(jù)按照每32位二進(jìn)制數(shù)為一組進(jìn)行傳輸,由于存儲(chǔ)順序的影響, 實(shí)際的字節(jié)傳輸順序是由高位字節(jié)到低位字節(jié)的傳輸順序 。 ??為了使通信的雙方都能夠理解數(shù)據(jù)分組所攜帶的源地址、目的地址以及分組的長(zhǎng)度等二進(jìn)制信息,無(wú)論是主機(jī)還是路由器,在發(fā)送每一個(gè)分組以前,都必須將二進(jìn)制信息轉(zhuǎn)換為TCP/IP標(biāo)準(zhǔn)的網(wǎng)絡(luò)字節(jié)順序格式。網(wǎng)絡(luò)字節(jié)順序格式的地址不受主機(jī)、路由器類型的影響,它的表示是唯一的。 ??
在Socket編程開發(fā)中,通過(guò)函數(shù)inet_addr和inet_ntoa可以實(shí)現(xiàn)點(diǎn)分字符串與網(wǎng)絡(luò)字節(jié)順序格式IP地址之間的轉(zhuǎn)換。 ??
? inet_addr函數(shù)原型如下: ??
[cpp]?view plaincopyprint?
?我們?cè)谇懊娴膕ocket編程提到client端的代碼,連接本地端口:
[cpp]?view plaincopyprint?
?
三、主機(jī)字節(jié)順序格式(HBO,Host ? Byte ? Order) ???
? ? ? ? 主機(jī)字節(jié)順序格式顧名思義,其IP地址的格式是和具體主機(jī)或者路由器相關(guān)的。對(duì)于不同的主機(jī),在進(jìn)行IP地址的存儲(chǔ)時(shí)有不同的格式,比如對(duì)于 Motorola ? 68k系列主機(jī),其HBO與NBO是相同的。而對(duì)于Intel ? x86系列,HBO與NBO則正好相反。 ??? ? ? ? 在Socket編程中,有四個(gè)函數(shù)來(lái)完成主機(jī)字節(jié)順序格式和網(wǎng)絡(luò)字節(jié)順序格式之間的轉(zhuǎn)換,它們是:htonl、htons、ntohl、和ntohs。 htons和ntohs完成16位無(wú)符號(hào)數(shù)的相互轉(zhuǎn)換,htonl和ntohl完成32位無(wú)符號(hào)數(shù)的相互轉(zhuǎn)換。 ??
? ? ? ? 在實(shí)際應(yīng)用中我們常見到將端口號(hào)轉(zhuǎn)換的例子(如上例)。這是因?yàn)?#xff0c;如果用戶輸入一個(gè)數(shù)字,而且將指定使用這一數(shù)字作為端口號(hào),應(yīng)用程序則必須在使用它建立地址以前,把它從主機(jī)字節(jié)順序轉(zhuǎn)換成網(wǎng)絡(luò)字節(jié)順序(使用htons()函數(shù)),以遵守TCP/IP協(xié)議規(guī)定的存儲(chǔ)標(biāo)準(zhǔn)。相應(yīng)地,如果應(yīng)用程序希望顯示包含于某一地址中的端口號(hào)(例如從getpeername()函數(shù)中返回的),這一端口號(hào)就必須在被顯示前從網(wǎng)絡(luò)順序轉(zhuǎn)換到主機(jī)順序(使用ntohs()函數(shù))。 ??
? ? ? ? 那么,對(duì)于IP地址,主機(jī)字節(jié)順序格式的轉(zhuǎn)換又有哪些應(yīng)用呢? ??
? ? ? ? 應(yīng)用一,如果想知道從202.156.2.23到202.156.9.65這兩個(gè)IP之間到底有多少個(gè)主機(jī)地址怎么辦?這時(shí)就可以將兩個(gè)IP地址轉(zhuǎn)換為主機(jī)字節(jié)順序的格式然后相減來(lái)得到,具體的實(shí)現(xiàn)如下: ??
[cpp]?view plaincopyprint?
即可,具體實(shí)現(xiàn)如下: ??
[cpp]?view plaincopyprint?
? ? ? 總結(jié) ??
? ? ? ?介紹了IP地址的三種不同表示格式,包括各種格式產(chǎn)生的原因、具體含義以及在Socket編程開發(fā)中的一些應(yīng)用。在實(shí)際應(yīng)用中,必須遵循應(yīng)用時(shí)所應(yīng)采用的格式標(biāo)準(zhǔn),同時(shí)還應(yīng)靈活運(yùn)用格式間的相互轉(zhuǎn)換以及計(jì)算技巧。
字節(jié)序相關(guān)知識(shí)
?1)字節(jié)序
| ? ? ? ? ? 字節(jié)序又稱端序,尾序,英文:Endianness。在計(jì)算機(jī)科學(xué)領(lǐng)域中,字節(jié)序是指存放多字節(jié)數(shù)據(jù)的字節(jié)(byte)的順序,典型的情況是整數(shù)在內(nèi)存中的存放方式和網(wǎng)絡(luò)傳輸的傳輸順序。Endianness有時(shí)候也可以用指位序(bit)。 ? ? ? ? 一般而言,字節(jié)序指示了一個(gè)UCS-2字符的哪個(gè)字節(jié)存儲(chǔ)在低地址。如果LSByte 在MSByte的前面,即LSB為低地址,則該字節(jié)序是小端序;反之則是大端序。在網(wǎng)絡(luò)編程中,字節(jié)序是一個(gè)必須被考慮的因素,因?yàn)椴煌奶幚砥黧w系可能采用不同的字節(jié)序。在多平臺(tái)的代碼編程中,字節(jié)序可能會(huì)導(dǎo)致難以察覺的bug。 名詞: 最低有效位(the least significant bit,lsb):是指一個(gè)二進(jìn)制數(shù)字中的第0位(即最低位),具有權(quán)值為2^0,可以用它來(lái)檢測(cè)數(shù)的奇偶性。與之相反的稱之為最高有效位。在大端序中,lsb指最右邊的位。
最高有效位(the Most Significant Bit,msb):是指一個(gè)n位二進(jìn)制數(shù)字中的n-1位,具有最高的權(quán)值。與之相反的稱之為最低有效位。在大端序中,msb即指最左端的位。 對(duì)于有符號(hào)二進(jìn)制數(shù),負(fù)數(shù)采用反碼或補(bǔ)碼形式,此時(shí)msb用來(lái)表示符號(hào),msb為1表示負(fù)數(shù),0表示正數(shù)。 |
|
單字節(jié)(abyte):大部分處理器以相同的順序處理位元(bit),因此單字節(jié)的存放方法和傳輸方式一般相同。 多字節(jié):如整數(shù)(32位機(jī)中一般占4字節(jié)),多字節(jié)對(duì)象被存儲(chǔ)為連續(xù)的字節(jié)序列,數(shù)據(jù)的內(nèi)存地址則是該內(nèi)存地址的最小地址。如long型數(shù)據(jù)的地址是ox001,?ox002,?ox003,ox004。則該數(shù)據(jù)的內(nèi)存地址是ox001。 在不同的處理器的存放多字節(jié)數(shù)據(jù)的方式主要有兩種: 大端序(英文名稱為big endian):指從最高位起存,位數(shù)最大的數(shù)字在最前,即高字節(jié)存于內(nèi)存低地址,低字節(jié)存于內(nèi)存高地址,?從最高有效字節(jié)到最低有效字節(jié)的順序存儲(chǔ)對(duì)象。 小端序(英文名稱為little endian):指從對(duì)低位起存,位數(shù)最小的數(shù)字在最前。 即低字節(jié)存于內(nèi)存低地址,高字節(jié)存于內(nèi)存高地址,從最低有效字節(jié)到最高有效字節(jié)的順序存儲(chǔ)對(duì)象。 簡(jiǎn)單打個(gè)比方說(shuō),十進(jìn)制數(shù)12345。1的位數(shù)最高,是萬(wàn)位;5的位數(shù)最低,是個(gè)位。? 大端序的話,就是從萬(wàn)位開始存,表示為12345;? 再如一個(gè)long型數(shù)據(jù)0x12345678的存儲(chǔ)表示: 大端序存儲(chǔ)表示:
小端序的存儲(chǔ)表示:
|
2)網(wǎng)絡(luò)序
網(wǎng)絡(luò)傳輸一般采用大端序,也被稱之為網(wǎng)絡(luò)字節(jié)序,或網(wǎng)絡(luò)序。IP協(xié)議中定義大端序?yàn)榫W(wǎng)絡(luò)字節(jié)序。
socketAPI定義了一組轉(zhuǎn)換函數(shù),用于16和32bit整數(shù)在網(wǎng)絡(luò)序和本機(jī)字節(jié)序之間的轉(zhuǎn)換。htonl,htons用于本機(jī)序轉(zhuǎn)換到網(wǎng)絡(luò)序;ntohl,ntohs用于網(wǎng)絡(luò)序轉(zhuǎn)換到本機(jī)序。
3)位序
一般用于描述串行設(shè)備的傳輸順序。一般硬件傳輸采用小端序(先傳低位),但I2C協(xié)議采用大端序。網(wǎng)絡(luò)協(xié)議中只有數(shù)據(jù)鏈路層的底端會(huì)涉及到。
4)處理器體系
?1)小端序體系:x86,MOS Technology 6502,Z80,VAX,PDP-11等處理器為L(zhǎng)ittleendian。
?2)大端序體系:Motorola 6800,Motorola 68000,PowerPC 970,System/370,SPARC(除V9外)等處理器為Big endian
?3)可配置:ARM,?PowerPC?(除PowerPC 970外),?DEC Alpha,?SPARCV9,?MIPS,?PA-RISC?and?IA64的字節(jié)序是可配置的。
5) 編程判斷大端序和小端序
[cpp]?view plaincopyprint?
設(shè)定斷點(diǎn):
打開 debug——>window——>Memory
查看變量a 的地址:0x002BFE50
查看內(nèi)存地址:
從上面看出我使用的x86?,是小端序。
從而驗(yàn)證 b =false是正確的。
?
總結(jié)
以上是生活随笔為你收集整理的IP地址的三种表示格式 及 在Socket编程中的应用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 网络异常检查
- 下一篇: 网络编程释疑之:单台服务器上的并发TCP