go語言的位元組序

2021-08-25 11:26:02 字數 2372 閱讀 8637

最近在看nsq的原始碼時候,發現它處理message的時候,都會採用位元組序進行資料報的處理,於是我覺得有必要深入了解下tcp協議中 位元組序的知識

我們一般把位元組(byte)看作是資料的最小單位。當然,其實乙個位元組中還包含8個bit (bit = binary digit)。 在乙個32位的cpu中「字長」為32個bit,也就是4個byte。在這樣的cpu中,總是以4位元組對齊的方式來讀取或寫入記憶體, 那麼同樣這4個位元組的資料是以什麼順序儲存在記憶體中的呢?我們下面詳細**一下。

位元組序包括:大端序和小端序,為什麼要這麼麻煩還要分門別類呢?舉個例子,255用二進位制表達就是1111 1111,再加1就是1 0000 0000,多了乙個1出來,顯然我們需要再用額外的乙個位元組來存放這個1,但是這個1要存放在第乙個位元組還是第二個位元組呢?這時候因為人們選擇的不同,就出現了大端序和小端序的差異。

而所謂大字節序(big endian),便是指其「最高有效位(most significant byte)」落在低位址上的儲存方式。例如像位址a寫入0x0a0b0c0d之後,在記憶體中的資料便是:

對於我們常用的cpu架構,如intel,amd的cpu使用的都是小字節序,而例如mac os以前所使用的power pc使用的便是大字節序(不過現在mac os也使用intel的cpu了)。

go中處理大小端序的**位於encoding/binary,包中的全域性變數bigendian用於操作大端序資料,littleendian用於操作小端序資料,這兩個變數所對應的資料型別都實行了byteorder介面:

type byteorder inte***ce

為了深入了解它們,我們先寫乙個程式觀察下go處理大端序和小端序的方式:

package main

import (

"encoding/binary"

"fmt"

"unsafe"

const int_size int = int(unsafe.sizeof(0))

//判斷我們系統中的位元組序型別

func systemedian() else {

fmt.println("system edian is big endian")

func testbigendian() {

// 0000 0000 0000 0000 0000 0001 1111 1111

var testint int32 = 256

fmt.printf("%d use big endian: \n", testint)

var testbytes byte = make(byte, 4)

binary.bigendian.putuint32(testbytes, uint32(testint))

fmt.println("int32 to bytes:", testbytes)

convint := binary.bigendian.uint32(testbytes)

fmt.printf("bytes to int32: %d\n\n", convint)

func testlittleendian() {

// 0000 0000 0000 0000 0000 0001 1111 1111

var testint int32 = 256

fmt.printf("%d use little endian: \n", testint)

var testbytes byte = make(byte, 4)

binary.littleendian.putuint32(testbytes, uint32(testint))

fmt.println("int32 to bytes:", testbytes)

convint := binary.littleendian.uint32(testbytes)

fmt.printf("bytes to int32: %d\n\n", convint)

func main() {

systemedian()

fmt.println("")

testbigendian()

testlittleendian()

執行的結果:

system edian is big endian

256 use big endian:

int32 to bytes: [0 0 1 0]

bytes to int32: 256

256 use little endian:

int32 to bytes: [0 1 0 0]

bytes to int32: 256

為了程式的相容,我們在開發跨伺服器的tcp服務時,每次傳送和接受資料都要進行轉換,這樣做的目的是保證**在任何計算機上執行時都能達到預期的效果。

大端位元組序 小端位元組序(網路位元組序 主機位元組序)

大端位元組序 整數的高位位元組儲存在記憶體的低位址處,低位元組儲存在記憶體的高位址處。一般pc大多採用小端位元組序,也稱為主機位元組序。網路上傳輸採用大端位元組序,也稱為網路位元組序。linux中常用轉換函式如下 include uint32 t htonl uint32 t hostlong 無符...

位元組序和網路位元組序

1 位元組序 由於不同的計算機系統採用不同的位元組序儲存資料,同樣乙個4位元組的32位整數,在記憶體中儲存的方式就不同.位元組序分為小尾位元組序 little endian 和大尾位元組序 big endian intel處理器大多數使用小尾位元組序,motorola處理器大多數使用大尾 big e...

位元組序和網路位元組序

1位元組序 由於不同的計算機系統採用不同的位元組序儲存資料,同樣乙個4位元組的32位整數,在記憶體中儲存的方式就不同.位元組序分為小尾位元組序 little endian 和大尾位元組序 big endian intel處理器大多數使用小尾位元組序,motorola處理器大多數使用大尾 big en...