ACD_CDR編譯時的4個宏、下面4個宏在ACE編譯時默認都是關閉的。
如果要讓自己的ACE庫有相關的能力需要在config.h中定義以下宏
ACE_InputCDR 相關的宏
ACE_CDR_IGNORE_ALIGNMENT
該宏讓CDR Stream忽略輸入流的字節對其,全部按單字節對其。
如果沒有設置該宏,ACE採用8個字節對輸入流進行默認對其。
ACE_DISABLE_SWAP_ON_READ
該宏靜止把輸入流賦值給多字節數據變量(2、4、8)時靜止高低字節序的交換。
默認情況下該宏關閉、也就是ACE_InputCDR會對字節序進行交換。
一般情況下我們不需要定義該宏、除非我們的系統中所有的網絡設備都是同一個字節體系的。否則必須關閉該宏。
ACE_OutputCDR 相關的宏
ACE_LACKS_CDR_ALIGNMENT
該宏打開後、忽略把多字節數據寫入輸出流時忽略字節對其、而是採用單字節對其的方式寫入。
默認ACE關閉該宏、此時ACE在寫入時會根據寫入數據的字節自動調整。也就是寫入Short、Int等類型時
起始地址調整爲 sizeof( datatype) 的整數倍數。即 startWriteAddre % sizeof( DataType) == 0
ACE_ENABLE_SWAP_ON_WRITE
該宏打開在寫入多字節數據類型時,自動進行字節序的交換。
關於字節序交換的問題:
1) ACE_InputCDR 、ACE_OutputCDR 何時會對讀取或者寫入的多字節數據進行字節序交換呢?
ACE_InputCDR 宏ACE_DISABLE_SWAP_ON_READ關閉時,而且其byte_order與本機的字節序不一致時.
ACE_OutputCDR 宏打開釋,而且ACE_OutputCDR對象的byte_order 與本機器的字節序不一致時.
關於PC編程的問題:
1. 由於網絡通信一般採用BIG字節序/也叫做網絡字節序.
2. 我們使用的PC機或者嵌入式系統可能使用BIG字節序也可能使用LITTEN(小字節序)
3. 當我們的編程環境爲LITTEN(小字節序)時,請繼續關注下面的問題.
ACE_InputCDR InputStream(NetWorkBuffer) ; // 假設 NetWorkBuffer 是從網絡上接受到的字節流
InputStream.reset_byte_order(ACE_CDR::BYTE_ORDER_BIG_ENDIAN);// 我們必須明確的指定我們現在在處理的數據的字節流的類型.
ACE_OutputCDR OutputStream(LocalBuffer); // 假設 LocalBuffer 是我們要發送到網絡對等體的數據緩存區
OutputStream.reset_byte_order(ACE_CDR::BYTE_ORDER_BIG_ENDIAN); // 由於網絡字節序採用的是BIG,所以我們要明確的指定.
4. 何時可以不比關注字節序問題.
4.1 通信的雙方都是相同的字節序/而且內部約定好採用了同一種字節序時.
如果你是一個老手/你一定不會忽略字節序問題的/否則隨着通信系統的複雜度的提高/你到時會頭大的,而且這樣的習慣從網絡編程的角度來說是極其不道德的.
ACE_CDR 對輸入輸出流使用倆組不同宏來控制/而且其默認規則都不太一樣,對剛剛開始使用ACE_CDR進行網絡編程的人都需要折騰一番的.
2組宏來控制ACE的網絡字節流可能使爲了提高控制靈活性吧--還是要問問ACE的設計者的意圖?
#define ACE_CDR_IGNORE_ALIGNMENT
/*
#ifdef ACE_DISABLE_SWAP_ON_READ
#undef ACE_DISABLE_SWAP_ON_READ # 取消該宏的定義. 定義該宏就歇菜了...
#endif
*/
#define ACE_LACKS_CDR_ALIGNMENT
#define ACE_ENABLE_SWAP_ON_WRITE