原文地址:https://blog.csdn.net/ybhjx/article/details/50475440 css 最近在寫一個短信下發功能,客戶端使用c#和java的短信網關的進行網絡通訊。html 以前使用java進行開發,一切正常,改用c#沒法收到網關應答。java 想了半天意識到是否是網絡字節序問題,c# java默認就是大端字節序,和網絡字節序是一至的,因此不轉換也不會有問題,windows 而c#在windows平臺上是小端字節序。數組 網絡發送字節流是按大端序發送,也就是從左到右發送,和c#的小端序相反,形成網關不能正常識別協議。網絡 嘗試c#中轉換一下字節序,通訊成功。架構 c#中字節序轉換有兩種方法。編碼 非字串使用 System.BitConverter.GetBytes()方法,先讀入字節數組中,而後再用Array.Reverse()對byte數組反序一下,獲得大端序字節數組。spa 代碼: short x = 6; byte[] a=System.BitConverter.GetBytes(x); //獲得小端字節序數組 Array.Reverse(a); //反轉數組轉成大端。
另外c#直接提供了網絡字節序轉換方法。 System.Net.IPAddress.HostToNetworkOrder(本機到網絡轉換) System.Net.IPAddress.NetworkToHostOrder(網絡字節轉成本機) 推薦使用這種方法,簡單有效。 代碼示例: short x = 6; short b = System.Net.IPAddress.HostToNetworkOrder(x); //把x轉成相應的大端字節數 byte[] bb = System.BitConverter.GetBytes(b); //這樣直接取到的就是大端字節序字節數組。
對於字符串型:使用 System.Text.Encoding.Default.GetBytes();直接取字串對應字節數組。 不知道爲何這個方法取到的直接就是大端字節數組。不用轉換。 後來查了一下,關於字串的字節序問題,由於gbk和utf-8都是以單個字節表示數字的,因此不存在字節序問題,在多個不一樣系統架構都用。對於utf-16,則是以雙字節表示一個整數,因此爲會有字節序問題,分大小端unicode。 System.Text.Encoding.Default.GetBytes();在個人簡體中文系統上是以gb2312的編碼,也就是單個字來進行編碼的,因此也不會有字節序問題。 補充:「對於任何字符編碼,編碼單元的順序是由編碼方案指定的,與endian無關。例如GBK的編碼單元是字節,用兩個字節表示一個漢字。這兩個字節的順序是固定的,不受CPU字節序的影響。UTF-16的編碼單元是word(雙字節),word之間的順序是編碼方案指定的,word內部的字節排列纔會受到endian的影響。」,因此utf-8也沒有字節序的問題。字節序問題之存在於須要使用兩個字節以上來表示整數。而UTF-8只是一串字節流,不存在字節序問題,不過將這些字節流翻譯成Unicode比其餘的傳輸方式複雜。以字節爲單位編碼的,不管一個漢字是多少個字節,都無字節序問題。 而剩下的, 就是字符編碼內部的字節序了。好比UTF-16是用兩個字節表示一個字符,可是這兩個字節內部如何排序,系統並不知道,因此必須指定字節序。可是UTF-8因爲幾個字節表示並不相同,必定要從那個表示長度的字節開始讀,至關於一開始就知道該從哪裏是隊頭隊尾,因此不存在字節序問題。 附上字節序說明:
爲何要注意字節序的問題呢?你可能這麼問。固然,若是你寫的程序只在單機環境下面運行,而且不和別人的程序打交道,那麼你徹底能夠忽略字節序的存在。可是,若是你的程序要跟別人的程序產生交互呢?尤爲是當你把你在微機上運算的結果運用到計算機羣上去的話。在這裏我想說說兩種語言。C/C++語言編寫的程序裏數據存儲順序是跟編譯平臺所在的CPU相關的,而JAVA編寫的程序則惟一採用big endian方式來存儲數據。試想,若是你用C/C++語言在x86平臺下編寫的程序跟別人的JAVA程序互通時會產生什麼結果?就拿上面的 0x12345678來講,你的程序傳遞給別人的一個數據,將指向0x12345678的指針傳給了JAVA程序,因爲JAVA採起big endian方式存儲數據,很天然的它會將你的數據翻譯爲0x78563412。什麼?居然變成另一個數字了?是的,就是這種後果。所以,在你的C程序傳給JAVA程序以前有必要進行字節序的轉換工做。
用文字說明可能比較抽象,下面用圖像加以說明。好比數字0x12345678在兩種不一樣字節序CPU中的存儲順序以下所示: Big Endian 低地址 高地址 -----------------------------------------> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 12 | 34 | 56 | 78 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Little Endian 低地址 高地址 -----------------------------------------> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 78 | 56 | 34 | 12 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
上面代碼利用IPAddress.NetworkToHostOrder( )方法實現大、小端轉換。 |