1. 程式人生 > >1-網路位元組序和ip地址

1-網路位元組序和ip地址

1. 位元組序

  之前我們在學習記憶體的時候可知,記憶體儲存資料也是有大端儲存和小端儲存的,對於網路資料流同樣有大端小端之分,那麼為什麼要定義網路位元組序呢?

  原因是讓不同cpu架構的計算機進行網路通訊時,位元組序不會混淆,因此tcp/ip協議規定了在網路中傳輸的位元組流資料採用大端位元組序。

這裡寫圖片描述
圖1-大端位元組序

  通常,傳送主機通常將傳送緩衝區中的資料按記憶體地址從低到高的順序發出,接收主機把從網路上接到的位元組依次儲存在接收緩衝區中,也是按記憶體地址從低到高的順序儲存(即先發出的資料是低地址,後發出的資料是高地址)。

2. 網路位元組序轉換函式

  對於有的計算機內部使用的位元組序與網路位元組序不同的,就需要對資料進行轉換,比如ip地址,埠號,那麼可以使用下面的轉換函式。

#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);

  上面這四個函式中uint32_t表示無符號32位整數,你會發現這幾個函式都長得很類似,其中在這些函式中,h表示主機,n表示網路,to表示轉換到,l表示32位長整數的ip地址,s表示16位短整數的埠號。

  這裡肯定會有一些同學有疑問,那麼ip地址為什麼是佔32位,埠號是佔16位呢?

  這是因為ip地址的格式是:255.255.255.255,公共分為4個部分,每一部分佔1位元組,1位元組佔8bit位,那麼1個ip地址用2機制表示就是32bit位了。

  由於埠號最大能表示65535號,那麼把65535換算成2進位制就是2^16 - 1,也就是16個bit位了。

3. ip地址是什麼

  生活中人們通常需要知道自己的居住地址,在網路中的同樣需要一個地址來唯一標識每一臺主機,這樣所有的裝置之間才能實現全球通訊,ip地址就是標識了一臺主機或路由裝置在因特網的位置,並且網際網路中的所有主機都要遵守這個ip地址結構。ip協議就可以通過ip地址結構把資料轉發到網際網路中的目的主機。

4. ip地址表示方法

一般ip地址的表示方法有以下三種:
  二進位制記法(1000 0001 0000 1011 0000 1011 11101111),每8bit位為一個位元組。
  點分十進位制記法(可讀性高)(129 11 11 239)
  十六進位制記法(登錄檔、程式設計使用)(第一種:0x810B0BEF ,第二種:810B0BEF 16)



  為了符合人類的程式設計習慣,ip地址一般使用點分十進位制來表示的,這是為了方便區分和記憶,但是由於計算機只認識0和1,所以在計算機中ip地址也是用二進位制的0和1來表示,在程式設計中通常以十六進位制來表示ip地址。由此可知,ip地址在不同使用場景下需要進行轉換。另外,IPv4 地址本質上是 32 位無符號整數。

5. IPv4地址轉換函式

  對於ip地址在網路中是以網路位元組序形式傳輸的,有時候需要將點分十進位制的ip地址轉換成網路位元組序的in_addr_t型別。下面這幾個函式就是對ip地址進行澱粉十進位制到in_addr_t型別之間的轉換,在早期ip地址的轉換函式只能轉換IPv4的地址。

// 將點分十進位制直接轉換成 in_addr 型別(推薦使用)
int inet_aton(const char *cp, struct in_addr *inp);

// 將點分十進位制轉換成 in_addr_t 型別,返回值儲存的是網路位元組序(不推薦使用)
in_addr_t inet_addr(const char *cp);

// 將 in_addr 地址轉換成點分十進位制,返回點分十進位制的ip地址。注意:這個函式是執行緒不安全的
char *inet_ntoa(struct in_addr in);

6. IPv4和IPv6地址轉換函式

  下面使用的ip地址轉換函式是隨IPv6出現的新函式,對於IPv4和IPv6都支援,可以把ip地址轉換轉換成點分10進位制來表示,比如:點分十進位制記法表示129.11. 11.239,這樣可讀性就顯得高很多了。

  inet_pton函式用來將點分十進位制的ip地址轉換為網路位元組序,函式名中的p就表示點分十進位制,n表示網路位元組序

函式原型:

#include <arpa/inet.h>
int inet_pton(int af, const char *src, void *dst);  

引數說明:
  af:選擇ip的版本(AF_INET代表ipv4,AF_INET6代表ipv6)
  src:源ip地址
  dst:轉換後的目標ip地址是網路位元組序(傳出引數)

返回值:
  成功返回1,無效格式返回0,出錯返回-1



inet_ntop函式用來將網路位元組序轉換為點分十進位制的ip地址

函式原型:

#include <arpa/inet.h>
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);  

引數說明:
  af:選擇ip的版本
  src:網路位元組序的ip地址
  dst:儲存轉換後的字串ip地址
  size:指定儲存字串ip地址的空間大小

返回值:
  成功返回ip地址(點分十進位制形式的),出錯則返回NULL

7. 通用的socketaddr資料結構

  linux早期是用sockaddr結構體來描述ipv4協議的,但是現在sockaddr結構體已經不推薦使用,因為歷史原因,套接字函式函式早期在設計時是使用的struct sockaddr結構體,後期又設計了struct sockaddr_in來替代struct sockaddr,所以當在呼叫套接字函式宣告傳遞引數的指標型別會存在問題,ANSI C標準提供瞭解決辦法:將sockaddr定義成void *型別,也就是說sockaddr是一個通用的套接字地址結構。

通用的套接字地址結構,sockaddr結構體資訊:

struct sockaddr {
    sa_family_t sa_family;  /* internet協議族, AF_xxx */
    char sa_data[14];       /*14位元組的協議地址*/
};



  在使用struct sockaddr的時候需要進行強制轉換成通用的套接字地址結構,即sockaddr結構:

//使用sockaddr_in定義
struct sockaddr_in addr;
//呼叫bind函式傳參時需要對sockaddr_in型別強轉成通用的sockaddr型別
bind((struct sockaddr *)&addr); 

8. 其他的套接字地址結構

這裡寫圖片描述
圖2-其他的套接字地址結構

sockaddr是早期用來表示IPv4地址的。

IPv4地址使用sockaddr_in結構體來表示,包括16位埠號,32為ip地址

IPv6地址用sockaddr_in6結構體表示,包括16位埠號、128位IP地址和一些控制欄位

unix網路程式設計中是用sockaddr_un結構體表示,各種socket地址結構體的開頭都是相同的,前16位表示整個結構體的長度,後16位表示地址型別。

IPv4、IPv6和Unix Domain Socket的地址型別分別定義為常數AF_INET、AF_INET6、AF_UNIX。

9. IPv4的sockaddr_in結構體

  IPv4地址用sockaddr_in結構體表示,包括16位埠號和32位IP地址,其中sin_addr成員的型別是一個in_addr結構體,該結構體中的s_addr成員就是用來儲存ipv4的地址。

struct in_addr{
    in_addr_t s_addr   //ipv4地址
};

struct sockaddr_in{
    short int sin_family;        //inernet地址族,如AF_INET(主機位元組序)
    unsigned short int sin_port;  //埠號佔16位(網路位元組序)
    struct in_addr sin_addr;     //internet地址,32位ipv4地址(網路位元組序)
    unsigned char sin_zero[8];   //以0填充(為了格式對齊的填充位)
}

  這樣的話,只要取得某種sockaddr結構體的首地址,就可以根據地址型別欄位確定結構體中的內容,因此我們在呼叫bind、accept、connect等套接字函式,應該將這些函式的引數都用通用的套接字地址struct sockaddr *型別表示,即在傳遞引數之前先強制轉換成struct sockaddr *型別。

相關推薦

1-網路位元組ip地址

1. 位元組序   之前我們在學習記憶體的時候可知,記憶體儲存資料也是有大端儲存和小端儲存的,對於網路資料流同樣有大端小端之分,那麼為什麼要定義網路位元組序呢?   原因是讓不同cpu架構的計算機進行網路通訊時,位元組序不會混淆,因此tcp/ip協議規定了在

網路位元組主機位元組

不同的CPU有不同的位元組序型別 這些位元組序是指整數在記憶體中儲存的順序 這個叫做主機序最常見的有兩種1. Little endian:將低序位元組儲存在起始地址2. Big endian:將高序位元組儲存在起始地址LE little-endian 最符合人的思維的位元組序地址低位儲存值的低位地址高位儲存值

網路位元組主機位元組詳解!!!

我們都知道,如今的通訊方式已經趨向與多樣化,異構通訊(計算機軟體(作業系統) +    計算機硬體(核心架構,ARM,x86)不同)也已經很普遍了,如,手機和電腦中的qq進行通訊,,, 同時,在計算

1.socket程式設計:socket程式設計,網路位元組,函式介紹,IP地址轉換函式,sockaddr資料結構,網路套接字函式,socket相關函式,TCP serverclient

 1Socket程式設計 socket這個詞可以表示很多概念: 在TCP/IP協議中,“IP地址+TCP或UDP埠號”唯一標識網路通訊中的一個程序,“IP 地址+埠號”就

1.socket基礎知識:埠;sockaddr_in;位元組轉換函式(本地/網路位元組);地址轉換函式

1.埠 在進行通訊的時候,要首先通過IP地址獲取主機 再通過Port用來區分和主機上的哪個應用程式通訊 2.IPv4套介面地址結構:網際套接字地質結構 sockaddr_in:man 7 ip 1.標頭檔案:netinet/in.h 2.sockaddr_in結構 struct

IP地址、埠號、網路位元組

一.IP地址1. 簡單認識    IP協議有兩個版本:IPv4和IPv6。        (1)IP地址在IP協議中,用來標識網路中不同主機的地址。        (2)對於IPv4來講,IP地址是一個4位元組,32位的整數;對於IPv6來講,IP地址是一個16位元組,128位的整數。(3)我們常用“點分十進

linux IP地址轉換及網路位元組

文獻參考: http://roclinux.cn/?p=1160 一、IP地址的表示法: 1、ASCII表示法: 210.25.132.181,也就是字串形式,英語叫做IPv4 numbers-and-dots notation。 2、整型表示法: 352

MSF魔鬼訓練營-3.1.1信息收集-通過DNSIP地址挖掘目標網絡信息

詳細 root https earch 滲透測試 出發 .com 域名查詢 測試 情報搜集環境站滲透測試全過程的80%~90% 一、外圍信息搜集(公開渠道信息搜集OSINT open source intelligence) 3.1.1信息收集-通過DNS和IP地址挖

大端 小端網路位元組說明

大端(Big-Endian)和小端(little-Endian)的起源 關於大端小端名詞的由來,有一個有趣的故事,來自於Jonathan Swift的《格利佛遊記》:Lilliput和Blefuscu這兩個強國在過去的36個月中一直在苦戰。 戰爭的原因:大家都知道,吃雞蛋的時候,原始的方法是打破

01大小端、網路位元組地址轉換函式的使用

#include <stdio.h> #include <string.h> #include <sys/socket.h> #include <sys/so

網路程式設計套接字、網路位元組及用udp寫客戶端服務端聊天程式

認識IP地址 IP協議有兩個版本:IPV4和IPV6。 IPV4:IPV4版本的IP地址是4位元組無符號整數。那麼就存在IP地址資源匱乏的時候,這時可以採用兩種方法: DHCP:ip地址動態分配(應用層協議); NAT: 地址替換; 但是這兩種方法只是暫時的有I

網路通訊之 位元組轉換原理與網路位元組、大端小端模式

     原因如下:網路協議規定接收到得第一個位元組是高位元組,存放到低地址,所以傳送時會首先去低地址取資料的高位元組。小端模式的多位元組資料在存放時,低地址存放的是低位元組,而被髮送方網路協議函式傳送時會首先去低地址取資料(想要取高位元組,真正取得是低位元組),接收方網路協議函式接收時會將接收到的第一個位元

inet_ntoa()網路位元組IP轉化為點分十進位制IP

程式示例1: 下面這個例子來自MSDN: #include <winsock2.h> #include <stdio.h> #include <windows.h> #pragma comment(lib, "wininet.lib") // link wi

大端儲存小端儲存,網路位元組

一、大端、小端 "大端"和"小端"表示多位元組值的哪一端儲存在該值的起始地址處;小端儲存在起始地址處,即是小端位元組序;大端儲存在起始地址處,即是大端位元組序; 或者說: 1.小端法(Little-Endian)就是低位位元組排放在記憶體的低地址端(即該值的起始地址),高

Linux 網路基礎知識之IP地址子網掩碼詳解

部分內容圖片截自慕課網 1. TCP/IP四層模型會對資料逐層打包,其中網路層負責打包IP包頭,而IP包頭拆開內容格式如下圖 注意:一般情況下IP包頭為20個位元組,160個bit大小,包括5行資料,但在IPV4協議下並非一定如此,可能包含其他資訊,

tcp/ip網路位元組

主機和網路位元組序的轉換最近使用C#進行網路開發,需要處理ISO8583報文,由於其中有些域是數值型的,於是在傳輸的時候涉及到了位元組序的轉換。位元組順序是指佔記憶體多於一個位元組型別的資料在記憶體中的存放順序,通常有兩種位元組順序,根據他們所處的位置我們分別稱為主機節序和網路位元組序。通常我們認為網路位元組

一些基本問題:大小端,網路位元組,socket程式設計函式的注意點,gdbcoredump除錯

1,什麼是大小端?大小端是指資料在記憶體的的存放順序,現代計算機一次能夠載入32bit或者64bit的資料或者指令,因而資料的存放順序影響它被裝載到整數的值。以小端來講:低地址存資料的低位,高地址存資料的高;而大端敲好反過來:高地址存低位,地址存高位。2.測試大小端測試大小端

.net驗證是否合法郵箱ip地址的方式

pre 是否 rem str catch bool valid add 則表達式 通常情況下第一時間會想到使用正則表達式去驗證,但由於正則表達式過於復雜或者沒有考慮到某些情況,從而導致問題或者判斷的效率低。下面通過另一種方式去判斷。 判斷是否合法郵箱: /// <s

第二期 計算機數制IP地址多多關照

網絡 基礎計算機的數制1、十進制數制0、1、2、3、4、5、6、7、8、9十個數字組成表示方式()10或字母D2、二進制二進制基於兩個數字,只有 0 和 1(任何數的0次方都等於1)表示方式()2或字母B3、十六進制十六進的基數是 16前十個數字是 0 到 9,後面是 A、B、C、D、E 和 F,分別表示 1

單實例asm,修改主機名ip地址後的重配置

file creat completed srs right session reat ati listen 修改主機名和ip地址之後的reconfigure asm 參考資料:How to Reconfigure Oracle Restart (文檔 ID 986740.