Look into it ~

          present
          隨筆 - 32, 文章 - 0, 評(píng)論 - 3, 引用 - 0
          數(shù)據(jù)加載中……

          2008年11月4日

          android軟件

              只有注冊(cè)用戶登錄后才能閱讀該文。閱讀全文

          posted @ 2008-11-20 16:24 LukeW 閱讀(36) | 評(píng)論 (0)編輯 收藏

          linux設(shè)備模型

          Linux 2.6內(nèi)核的一個(gè)重要特色是提供了統(tǒng)一的內(nèi)核設(shè)備模型。隨著技術(shù)的不斷進(jìn)步,系統(tǒng)的拓?fù)浣Y(jié)構(gòu)越來(lái)越復(fù)雜,對(duì)智能電源管理、熱插拔以及plug and play的支持要求也越來(lái)越高,2.4內(nèi)核已經(jīng)難以滿足這些需求。為適應(yīng)這種形勢(shì)的需要,2.6內(nèi)核開(kāi)發(fā)了全新的設(shè)備模型。
          1. Sysfs文件系統(tǒng)
          Sysfs文件系統(tǒng)是一個(gè)類似于proc文件系統(tǒng)的特殊文件系統(tǒng),用于將系統(tǒng)中的設(shè)備組織成層次結(jié)構(gòu),并向用戶模式程序提供詳細(xì)的內(nèi)核數(shù)據(jù)結(jié)構(gòu)信息。其頂層目錄主要有:
          Block目錄:包含所有的塊設(shè)備
          Devices目錄:包含系統(tǒng)所有的設(shè)備,并根據(jù)設(shè)備掛接的總線類型組織成層次結(jié)構(gòu)
          Bus目錄:包含系統(tǒng)中所有的總線類型
          Drivers目錄:包括內(nèi)核中所有已注冊(cè)的設(shè)備驅(qū)動(dòng)程序
          Class目錄:系統(tǒng)中的設(shè)備類型(如網(wǎng)卡設(shè)備,聲卡設(shè)備等)
          2. 內(nèi)核對(duì)象機(jī)制關(guān)鍵數(shù)據(jù)結(jié)構(gòu)
          2.1 kobject內(nèi)核對(duì)象
          Kobject 是Linux 2.6引入的新的設(shè)備管理機(jī)制,在內(nèi)核中由struct kobject表示。通過(guò)這個(gè)數(shù)據(jù)結(jié)構(gòu)使所有設(shè)備在底層都具有統(tǒng)一的接口,kobject提供基本的對(duì)象管理,是構(gòu)成Linux 2.6設(shè)備模型的核心結(jié)構(gòu),它與sysfs文件系統(tǒng)緊密關(guān)聯(lián),每個(gè)在內(nèi)核中注冊(cè)的kobject對(duì)象都對(duì)應(yīng)于sysfs文件系統(tǒng)中的一個(gè)目錄。
          Kobject結(jié)構(gòu)定義為:
          struct kobject {
          char * k_name;    // 指向設(shè)備名稱的指針
          char name[KOBJ_NAME_LEN];   // 設(shè)備名稱
          struct kref kref;    // 對(duì)象引用計(jì)數(shù)
          struct list_head entry;   // 掛接到所在kset中去的單元
          struct kobject * parent; // 指向父對(duì)象的指針
          struct kset * kset;    // 所屬kset的指針
          struct kobj_type * ktype;   // 指向其對(duì)象類型描述符的指針
          struct dentry * dentry; // sysfs文件系統(tǒng)中與該對(duì)象對(duì)應(yīng)的文件節(jié)點(diǎn)路徑指針
          };

          其中的kref域表示該對(duì)象引用的計(jì)數(shù),內(nèi)核通過(guò)kref實(shí)現(xiàn)對(duì)象引用計(jì)數(shù)管理,內(nèi)核提供兩個(gè)函數(shù)kobject_get()、kobject_put()分別用于增加和減少引用計(jì)數(shù),當(dāng)引用計(jì)數(shù)為0時(shí),所有該對(duì)象使用的資源將被釋放。
          Ktype 域是一個(gè)指向kobj_type結(jié)構(gòu)的指針,表示該對(duì)象的類型。Kobj_type數(shù)據(jù)結(jié)構(gòu)包含三個(gè)域:一個(gè)release方法用于釋放kobject占 用的資源;一個(gè)sysfs_ops指針指向sysfs操作表和一個(gè)sysfs文件系統(tǒng)缺省屬性列表。Sysfs操作表包括兩個(gè)函數(shù)store()和 show()。當(dāng)用戶態(tài)讀取屬性時(shí),show()函數(shù)被調(diào)用,該函數(shù)編碼指定屬性值存入buffer中返回給用戶態(tài);而store()函數(shù)用于存儲(chǔ)用戶態(tài) 傳入的屬性值。
          2.2 kset內(nèi)核對(duì)象集合
          Kobject通常通過(guò)kset組織成層次化的結(jié)構(gòu),kset是具有相同類型的kobject的集合,在內(nèi)核中用kset數(shù)據(jù)結(jié)構(gòu)表示,定義為:
          struct kset {
          struct subsystem * subsys;   // 所在的subsystem的指針
          struct kobj_type * ktype;   // 指向該kset對(duì)象類型描述符的指針
          struct list_head list;      // 用于連接該kset中所有kobject的鏈表頭
          struct kobject kobj;    // 嵌入的kobject
          struct kset_hotplug_ops * hotplug_ops; // 指向熱插拔操作表的指針
          };

          包 含在kset中的所有kobject被組織成一個(gè)雙向循環(huán)鏈表,list域正是該鏈表的頭。Ktype域指向一個(gè)kobj_type結(jié)構(gòu),被該 kset中的所有kobject共享,表示這些對(duì)象的類型。Kset數(shù)據(jù)結(jié)構(gòu)還內(nèi)嵌了一個(gè)kobject對(duì)象(由kobj域表示),所有屬于這個(gè)kset 的kobject對(duì)象的parent域均指向這個(gè)內(nèi)嵌的對(duì)象。此外,kset還依賴于kobj維護(hù)引用計(jì)數(shù):kset的引用計(jì)數(shù)實(shí)際上就是內(nèi)嵌的 kobject對(duì)象的引用計(jì)數(shù)。
          2.3 subsystem內(nèi)核對(duì)象子系統(tǒng)
          Subsystem是一系列kset的集合,描述系統(tǒng)中某一 類設(shè)備子系統(tǒng),如block_subsys表示所有的塊設(shè)備,對(duì)應(yīng)于sysfs文件系統(tǒng)中的block目錄。類似的,devices_subsys對(duì)應(yīng)于 sysfs中的devices目錄,描述系統(tǒng)中所有的設(shè)備。Subsystem由struct subsystem數(shù)據(jù)結(jié)構(gòu)描述,定義為:
          struct subsystem {
          struct kset kset;       // 內(nèi)嵌的kset對(duì)象
          struct rw_semaphore rwsem; // 互斥訪問(wèn)信號(hào)量
          };

          每 個(gè)kset必須屬于某個(gè)subsystem,通過(guò)設(shè)置kset結(jié)構(gòu)中的subsys域指向指定的subsystem可以將一個(gè)kset加入到該 subsystem。所有掛接到同一subsystem的kset共享同一個(gè)rwsem信號(hào)量,用于同步訪問(wèn)kset中的鏈表。

          3. 內(nèi)核對(duì)象機(jī)制主要相關(guān)函數(shù)
          針對(duì)內(nèi)核對(duì)象不同層次的數(shù)據(jù)結(jié)構(gòu),linux 2.6內(nèi)核定義了一系列操作函數(shù),定義于lib/kobject.c文件中。
          3.1 kobject相關(guān)函數(shù)
          void kobject_init(struct kobject * kobj);// kobject初始化函數(shù)。設(shè)置kobject引用計(jì)數(shù)為1,entry域指向自身,其所屬kset引用計(jì)數(shù)加1

          int kobject_set_name(struct kobject *kobj, const char *format, );// 設(shè)置指定kobject的名稱。

          void kobject_cleanup(struct kobject * kobj);
          void kobject_release(struct kref *kref);// kobject清除函數(shù)。當(dāng)其引用計(jì)數(shù)為0時(shí),釋放對(duì)象占用的資源。

          struct kobject *kobject_get(struct kobject *kobj);// 將kobj 對(duì)象的引用計(jì)數(shù)加1,同時(shí)返回該對(duì)象的指針。

          void kobject_put(struct kobject * kobj);// 將kobj對(duì)象的引用計(jì)數(shù)減1,如果引用計(jì)數(shù)降為0,則調(diào)用kobject_release()釋放該kobject對(duì)象。

          int kobject_add(struct kobject * kobj);// 將kobj對(duì)象加入Linux設(shè)備層次。掛接該kobject對(duì)象到kset的list鏈中,增加父目錄各級(jí)kobject的引用計(jì)數(shù),在其parent指向的目錄下創(chuàng)建文件節(jié)點(diǎn),并啟動(dòng)該類型內(nèi)核對(duì)象的hotplug函數(shù)。

          int kobject_register(struct kobject * kobj);// kobject注冊(cè)函數(shù)。通過(guò)調(diào)用kobject_init()初始化kobj,再調(diào)用kobject_add()完成該內(nèi)核對(duì)象的注冊(cè)。

          void kobject_del(struct kobject * kobj);// 從Linux設(shè)備層次(hierarchy)中刪除kobj對(duì)象。

          void kobject_unregister(struct kobject * kobj);// kobject注銷函數(shù)。與kobject_register()相反,它首先調(diào)用kobject_del從設(shè)備層次中刪除該對(duì)象,再調(diào)用kobject_put()減少該對(duì)象的引用計(jì)數(shù),如果引用計(jì)數(shù)降為0,則釋放該kobject對(duì)象。

          3.2 kset相關(guān)函數(shù)
          與kobject 相似,kset_init()完成指定kset的初始化,kset_get()和kset_put()分別增加和減少kset對(duì)象的引用計(jì)數(shù)。 Kset_add()和kset_del()函數(shù)分別實(shí)現(xiàn)將指定keset對(duì)象加入設(shè)備層次和從其中刪除;kset_register()函數(shù)完成 kset的注冊(cè)而kset_unregister()函數(shù)則完成kset的注銷。
          3.3 subsystem相關(guān)函數(shù)
          subsystem有一組完成類似的函數(shù),分別是:
          void subsystem_init(struct subsystem *subsys);
          int subsystem_register(struct subsystem *subsys);
          void subsystem_unregister(struct subsystem *subsys);
          struct subsystem *subsys_get(struct subsystem *subsys)
          void subsys_put(struct subsystem *subsys);

          4. 設(shè)備模型組件
          在上述內(nèi)核對(duì)象機(jī)制的基礎(chǔ)上,Linux的設(shè)備模型建立在幾個(gè)關(guān)鍵組件的基礎(chǔ)上,下面我們?cè)敿?xì)闡述這些組件。
          4.1 devices
          系統(tǒng)中的任一設(shè)備在設(shè)備模型中都由一個(gè)device對(duì)象描述,其對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu)struct device定義為:
          struct device {
          struct list_head g_list;
          struct list_head node;
              
          struct list_head bus_list;
              
          struct list_head driver_list;
              
          struct list_head children;
              
          struct device *parent;
              
          struct kobject kobj;
              
          char bus_id[BUS_ID_SIZE];
              
          struct bus_type *bus;
              
          struct device_driver *driver;
              
          void *driver_data;
              
          /* Several fields omitted */
          };

          g_list 將該device對(duì)象掛接到全局設(shè)備鏈表中,所有的device對(duì)象都包含在devices_subsys中,并組織成層次結(jié)構(gòu)。Node域?qū)⒃搶?duì)象掛接 到其兄弟對(duì)象的鏈表中,而bus_list則用于將連接到相同總線上的設(shè)備組織成鏈表,driver_list則將同一驅(qū)動(dòng)程序管理的所有設(shè)備組織為鏈 表。此外,children域指向該device對(duì)象子對(duì)象鏈表頭,parent域則指向父對(duì)象。Device對(duì)象還內(nèi)嵌一個(gè)kobject對(duì)象,用于引 用計(jì)數(shù)管理并通過(guò)它實(shí)現(xiàn)設(shè)備層次結(jié)構(gòu)。Driver域指向管理該設(shè)備的驅(qū)動(dòng)程序?qū)ο螅鴇river_data則是提供給驅(qū)動(dòng)程序的數(shù)據(jù)。Bus域描述設(shè) 備所連接的總線類型。
          內(nèi)核提供了相應(yīng)的函數(shù)用于操作device對(duì)象。其中Device_register()函數(shù)將一個(gè)新的device對(duì)象插 入設(shè)備模型,并自動(dòng)在/sys/devices下創(chuàng)建一個(gè)對(duì)應(yīng)的目錄。Device_unregister()完成相反的操作,注銷設(shè)備對(duì)象。 Get_device()和put_device()分別增加與減少設(shè)備對(duì)象的引用計(jì)數(shù)。通常device結(jié)構(gòu)不單獨(dú)使用,而是包含在更大的結(jié)構(gòu)中作為一 個(gè)子結(jié)構(gòu)使用,比如描述PCI設(shè)備的struct pci_dev,其中的dev域就是一個(gè)device對(duì)象。
          4.2 drivers
          系統(tǒng)中的每個(gè)驅(qū)動(dòng)程序由一個(gè)device_driver對(duì)象描述,對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu)定義為:
          struct device_driver {
              
          char *name;   // 設(shè)備驅(qū)動(dòng)程序的名稱
              struct bus_type *bus; // 該驅(qū)動(dòng)所管理的設(shè)備掛接的總線類型
              struct kobject kobj;    // 內(nèi)嵌kobject對(duì)象
              struct list_head devices;  // 該驅(qū)動(dòng)所管理的設(shè)備鏈表頭
              int (*probe)(struct device *dev); // 指向設(shè)備探測(cè)函數(shù),用于探測(cè)設(shè)備是否可以被該驅(qū)動(dòng)程序管理
          int (*remove)(struct device *dev); // 用于刪除設(shè)備的函數(shù)
          /*
           some fields omitted*/
          };

          與device 結(jié)構(gòu)類似,device_driver對(duì)象依靠?jī)?nèi)嵌的kobject對(duì)象實(shí)現(xiàn)引用計(jì)數(shù)管理和層次結(jié)構(gòu)組織。內(nèi)核提供類似的函數(shù)用于操作 device_driver對(duì)象,如get_driver()增加引用計(jì)數(shù),driver_register()用于向設(shè)備模型插入新的driver對(duì) 象,同時(shí)在sysfs文件系統(tǒng)中創(chuàng)建對(duì)應(yīng)的目錄。Device_driver()結(jié)構(gòu)還包括幾個(gè)函數(shù),用于處理熱拔插、即插即用和電源管理事件。
          4.3   buses
          系統(tǒng)中總線由struct bus_type描述,定義為:
          struct bus_type {
          char   * name; // 總線類型的名稱
          struct subsystem subsys; // 與該總線相關(guān)的subsystem
          struct kset drivers; // 所有與該總線相關(guān)的驅(qū)動(dòng)程序集合
          struct kset devices; // 所有掛接在該總線上的設(shè)備集合
          struct bus_attribute * bus_attrs; // 總線屬性
          struct device_attribute * dev_attrs; // 設(shè)備屬性
          struct driver_attribute * drv_attrs;   // 驅(qū)動(dòng)程序?qū)傩?/span>
          int (*match)(struct device * dev, struct device_driver * drv);
          int (*hotplug) (struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size);
          int (*suspend)(struct device * dev, u32 state);
          int (*resume)(struct device * dev);
          };

          每 個(gè)bus_type對(duì)象都內(nèi)嵌一個(gè)subsystem對(duì)象,bus_subsys對(duì)象管理系統(tǒng)中所有總線類型的subsystem對(duì)象。每個(gè) bus_type對(duì)象都對(duì)應(yīng)/sys/bus目錄下的一個(gè)子目錄,如PCI總線類型對(duì)應(yīng)于/sys/bus/pci。在每個(gè)這樣的目錄下都存在兩個(gè)子目 錄:devices和drivers(分別對(duì)應(yīng)于bus_type結(jié)構(gòu)中的devices和drivers域)。其中devices子目錄描述連接在該總 線上的所有設(shè)備,而drivers目錄則描述與該總線關(guān)聯(lián)的所有驅(qū)動(dòng)程序。與device_driver對(duì)象類似,bus_type結(jié)構(gòu)還包含幾個(gè)函數(shù) (match()、hotplug()等)處理相應(yīng)的熱插拔、即插即拔和電源管理事件。
          4.4 classes
          系統(tǒng)中的設(shè)備類由 struct class描述,表示某一類設(shè)備。所有的class對(duì)象都屬于class_subsys子系統(tǒng),對(duì)應(yīng)于sysfs文件系統(tǒng)中的/sys/class目錄。 每個(gè)class對(duì)象包括一個(gè)class_device鏈表,每個(gè)class_device對(duì)象表示一個(gè)邏輯設(shè)備,并通過(guò)struct class_device中的dev域(一個(gè)指向struct device的指針)關(guān)聯(lián)一個(gè)物理設(shè)備。這樣,一個(gè)邏輯設(shè)備總是對(duì)應(yīng)于一個(gè)物理設(shè)備,但是一個(gè)物理設(shè)備卻可能對(duì)應(yīng)于多個(gè)邏輯設(shè)備。此外,class結(jié)構(gòu)中 還包括用于處理熱插拔、即插即拔和電源管理事件的函數(shù),這與device對(duì)象和driver對(duì)象相似。

          posted @ 2008-11-12 23:14 LukeW 閱讀(189) | 評(píng)論 (0)編輯 收藏

          位運(yùn)算

          C中的位運(yùn)算
          能夠運(yùn)用到任何整形的數(shù)據(jù)類型上(包括char, int), 無(wú)論有沒(méi)有short, long, unsigned這樣的限定詞.


          位運(yùn)算的應(yīng)用
          // 交換指針變量x,y所指向的存儲(chǔ)位置處存放的值
          // 優(yōu)勢(shì)是不需要第三個(gè)位置來(lái)臨時(shí)存儲(chǔ)另一個(gè)值
          // 但是這個(gè)方法并沒(méi)有明顯的性能優(yōu)勢(shì),只是一個(gè)智力上的消遣
          void inplace_swap(int *x, int *y)
          {
           
          *= *^ *y;
           
          *= *^ *y;
           
          *= *^ *y;
          }

          位運(yùn)算常見(jiàn)用法:
          實(shí)現(xiàn)掩碼運(yùn)算



          -----------------------------------
          Java中的位運(yùn)算


          posted @ 2008-11-12 13:53 LukeW 閱讀(135) | 評(píng)論 (0)編輯 收藏

          大端小端 -- 各系統(tǒng)及機(jī)器的信息表示

          因?yàn)楝F(xiàn)行的計(jì)算機(jī)都是以八位一個(gè)字節(jié)為存儲(chǔ)單位,那么一個(gè)16位的整數(shù),也就是C語(yǔ)言中的short,在內(nèi)存中可能有兩種存儲(chǔ)順序big-

          endian和litte-endian.考慮一個(gè)short整數(shù)0x3132(0x32是低位,0x31是高位),把它賦值給一個(gè)short變量,那么它在內(nèi)存中的存儲(chǔ)可

          能有如下兩種情況:
          大端字節(jié)(Big-endian):

          short變量地址
                 0x1000                  0x1001
          ___________________________________
          |                 |
          |         0x31    |       0x32
          |________________ | ________________
          高位字節(jié)在低位字節(jié)的前面,也就是高位在內(nèi)存地址低的一端.可以這樣記住(大端->高位->在前->正常的邏輯順序)
           
          小端字節(jié)(little-endian):

          short變量地址
                 0x1000                  0x1001
          _____________________________________
          |                 |
          |         0x32    |       0x31
          |________________ | __________________
          低位字節(jié)在高位字節(jié)的前面,也就是低位在內(nèi)存地址低的一端.可以這樣記住(小端->低位->在前->與正常邏輯順序相反)
           
          可以做個(gè)實(shí)驗(yàn)
          在windows上下如下程序
          #include <stdio.h>
          #include 
          <assert.h>
           
          void main( void )
          {
                  
          short test;
                  FILE
          * fp;
                  
                  test 
          = 0x3132;  //(31ASIIC碼的’1’,32ASIIC碼的’2’)
                  if ((fp = fopen ("c:""test.txt""wb")) == NULL)
                        assert(
          0);
                  fwrite(
          &test, sizeof(short), 1, fp);
                  fclose(fp);
          }

              然后在C盤下打開(kāi)test.txt文件,可以看見(jiàn)內(nèi)容是21,而test等于0x3132,可以明顯的看出來(lái)x86的字節(jié)順序是低位在前.如果我們
          把這段同樣的代碼放到(big-endian)的機(jī)器上執(zhí)行,那么打出來(lái)的文件就是12.這在本機(jī)中使用是沒(méi)有問(wèn)題的.但當(dāng)你把這個(gè)文件從一
          個(gè)big- endian機(jī)器復(fù)制到一個(gè)little-endian機(jī)器上時(shí)就出現(xiàn)問(wèn)題了.

              如上述例子,我們?cè)赽ig-endian的機(jī)器上創(chuàng)建了這個(gè)test文件,把其復(fù)制到little-endian的機(jī)器上再用fread讀到一個(gè) short里
          面,我們得到的就不再是0x3132而是0x3231了,這樣讀到的數(shù)據(jù)就是錯(cuò)誤的,所以在兩個(gè)字節(jié)順序不一樣的機(jī)器上傳輸數(shù)據(jù)時(shí)需要特別
          小心字節(jié)順序,理解了字節(jié)順序在可以幫助我們寫出移植行更高的代碼.

          正因?yàn)橛凶止?jié)順序的差別,所以在網(wǎng)絡(luò)傳輸?shù)臅r(shí)候定義了所有字節(jié)順序相關(guān)的數(shù)據(jù)都使用big-endian,BSD的代碼中定義了四個(gè)宏來(lái)處
          理:
          #define ntohs(n)     //網(wǎng)絡(luò)字節(jié)順序到主機(jī)字節(jié)順序 n代表net, h代表host, s代表short
          #define htons(n)     //主機(jī)字節(jié)順序到網(wǎng)絡(luò)字節(jié)順序 n代表net, h代表host, s代表short
          #define ntohl(n)      //網(wǎng)絡(luò)字節(jié)順序到主機(jī)字節(jié)順序 n代表net, h代表host, s代表 long
          #define htonl(n)      //主機(jī)字節(jié)順序到網(wǎng)絡(luò)字節(jié)順序 n代表net, h代表host, s代表 long

          舉例說(shuō)明下這其中一個(gè)宏的實(shí)現(xiàn):
           #define sw16(x) "
              ((
          short)( "
                  (((short)(x) & (short)0x00ffU<< 8| "
                  (((short)(x) & (short)0xff00U>> 8) ))

          這里實(shí)現(xiàn)的是一個(gè)交換兩個(gè)字節(jié)順序.其他幾個(gè)宏類似.

          我們改寫一下上面的程序
          #include <stdio.h>
          #include 
          <assert.h>

          #define sw16(x) "
              ((
          short)( "
                  (((short)(x) & (short)0x00ffU<< 8| "
                  (((short)(x) & (short)0xff00U>> 8) ))

          // 因?yàn)閤86下面是低位在前,需要交換一下變成網(wǎng)絡(luò)字節(jié)順序
          #define htons(x) sw16(x)
           
          void main( void )
          {
                  
          short test;
                  FILE
          * fp;
                  
                  test 
          = htons(0x3132); //(31ASIIC碼的’1’,32ASIIC碼的’2’)
                  if ((fp = fopen ("c:""test.txt""wb")) == NULL)
                        assert(
          0);
                  fwrite(
          &test, sizeof(short), 1, fp);
                  fclose(fp);
          }

           
              如果在高字節(jié)在前的機(jī)器上,由于與網(wǎng)絡(luò)字節(jié)順序一致,所以我們什么都不干就可以了,只需要把#define htons(x) sw16(x)宏替

          換為 #define htons(x) (x).
              一開(kāi)始我在理解這個(gè)問(wèn)題時(shí),總在想為什么其他數(shù)據(jù)不用交換字節(jié)順序?比如說(shuō)我們write一塊buffer到文件,最后終于想明白了,

          因?yàn)槎际莡nsigned char類型一個(gè)字節(jié)一個(gè)字節(jié)的寫進(jìn)去,這個(gè)順序是固定的,不存在字節(jié)順序的問(wèn)題.

          【用函數(shù)判斷系統(tǒng)是Big Endian還是Little Endian】


          bool IsBig_Endian()
          //如果字節(jié)序?yàn)閎ig-endian,返回true;
          //反之為   little-endian,返回false
          {
              unsigned 
          short test = 0x1122;
              
          if(*( (unsigned char*&test ) == 0x11)
                 
          return TRUE;
          else
              
          return FALSE;

          }
          //IsBig_Endian()

          【打印程序?qū)ο蟮淖止?jié)表示】
          // 可在不同平臺(tái)與硬件架構(gòu)的機(jī)器中測(cè)試運(yùn)行這段代碼,理解大端表示和小端表示的不同.
          // 這段代碼使用強(qiáng)制類型轉(zhuǎn)換規(guī)避類型系統(tǒng)
          #incluede <stdio.h>

          // 假設(shè)每個(gè)字節(jié)都是非負(fù)整數(shù)
          typedef unsigned char *byte_pointer;

          void show_bytes(byte_pointer start, int len)
          {
           
          for(int i = 0; i < len; i++)
            printf(
          " %.2x", start[i]);
           printf(
          "\n");
          }

          void show_int(int x)
          {
           show_bytes((byte_pointer) 
          &x, sizeof(int));
          }

          void show_float(float x)
          {
           show_bytes((byte_pointer) 
          &x, sizeof(float));
          }

          // 在使用相同編碼(如ASCII編碼)的系統(tǒng)中,字符串字節(jié)表示得到的結(jié)果一般是相同的.所以文本數(shù)據(jù)比二進(jìn)制數(shù)據(jù)具有更強(qiáng)的平臺(tái)無(wú)關(guān)性
          void show_string(char *x)
          {
           show_bytes((byte_pointer) x, strlen(x));
          }

          void show_pointer(void *x)
          {
           show_bytes((byte_pointer) 
          &x, sizeof(void *));
          }

          void test_show_bytes(int val)
          {
           
          int ival = val;
           
          float fval = (float)ival;
           
          int *pval = &ival;
           
           show_int(ival); 
          // 各個(gè)機(jī)器因?yàn)榇蠖吮硎竞托《吮硎镜牟煌?從而只是字節(jié)順序不同
           show_float(fval); // 各個(gè)機(jī)器因?yàn)榇蠖吮硎竞托《吮硎镜牟煌?從而只是字節(jié)順序不同
           show_pointer(pval); // 指針值是與機(jī)器相關(guān)的(linux,sun使用4字節(jié)地址, 而alpha使用八字節(jié)地址)
          }

          ---------------------------------------------
          對(duì)于如數(shù)值12345在int型和float型時(shí)的編碼表示

          posted @ 2008-11-12 11:58 LukeW 閱讀(659) | 評(píng)論 (0)編輯 收藏

          點(diǎn)子

              只有注冊(cè)用戶登錄后才能閱讀該文。閱讀全文

          posted @ 2008-11-06 18:17 LukeW 閱讀(44) | 評(píng)論 (0)編輯 收藏

          j2me 聯(lián)網(wǎng)技術(shù)分析總結(jié)

          基本點(diǎn):

          Generic Connections

          In the CLDC Generic Connection framework, all connections are created using the open static method from the Connector class. If successful, this method returns an object that implements one of the generic connection interfaces. Figure 1 shows how these interfaces form an is-a hierarchy. The Connection interface is the base interface such that StreamConnectionNotifier is a Connection and InputConnection is a Connection too.

          fig1.gif
          Figure 1: Connection interface hierarchy
          • The Connection interface is the most basic connection type. It can only be opened and closed.
          • The InputConnection interface represents a device from which data can be read. Its openInputStream method returns an input stream for the connection.
          • The OuputConnection interface represents a device to which data can be written. Its openOutputStream method returns an output stream for the connection.
          • The StreamConnection interface combines the input and output connections.
          • The ContentConnection is a subinterface of StreamConnection. It provides access to some of the basic meta data information provided by HTTP connections.
          • The StreamConnectionNotified waits for a connection to be established. It returns a StreamConnection on which a communication link has ben established.
          • The DatagramConnection represents a datagram endpoint.

          The open method of the Connector class has the following syntax, where the String parameter has the format "protocol:address;parameters".

          Connector.open(String);

          Here are a few examples:

          HTTP Connection

          Connector.open("http://java.sun.com/developer");

          Datagram Connection

          Connector.open("datagram://address:port#");

          Communicate with a Port

          Connector.open("comm:0;baudrate=9600');

          Open Files

          Connector.open("file:/myFile.txt");


          The HttpConnection Interface:

          The HTTP protocol is a request-response application protocol in which the parameters of the request must be set before the request is sent. The connection could be in one of the three following states:
          • Setup: No connection yet
          • Connected: Connection has been made, the request has been sent, and some response is expected
          • Closed: Connection is closed

          In the setup state the following methods can be invoked:

          • setRequestMethod
          • setRequestProperty

          For example, suppose you have this connection:

          HttpConnection c = (HttpConnection)
          Connector.open(
          "http://java.sun.com/developer");

          Then, you can set the request method to be of type POST as follows:

          c.setRequestMethod(HttpConnection.POST);

          And likewise, you can set some of the HTTP properties. For example, you can set the User-Agent as follows:

          c.setRequestProperty("User-Agent","Profile/MIDP-1.0 Configuration/CLDC-1.0");

          If there is a method that requires data to be sent or received from the server, there is a state transition from Setup to Connected. Examples of methods that cause the transition include:

          openInputStream
          openOutputStream
          openDataInputStream
          openDataOutputStream
          getLength
          getType
          getDate
          getExpiration

          And while the connection is open, some of these methods that may be invoked:

          getURL
          getProtocol
          getHost
          getPort


          ------------------------------------------------------------
          要注意的問(wèn)題:
          開(kāi)發(fā)中遇到個(gè)很頭疼的問(wèn)題, 與服務(wù)器通信write()數(shù)據(jù)時(shí)報(bào)java.io.IOException: Couldn't write to socket.
          但是服務(wù)器抓不到任何包. 一開(kāi)始懷疑是連建立連接出的問(wèn)題, 實(shí)際上服務(wù)器抓不到包也有可能是流在沒(méi)有close的時(shí)候就已經(jīng)報(bào)錯(cuò)了.
          如:
          conn.open("url");
          out = conn.openDataOutputStream();//此時(shí)將進(jìn)行與服務(wù)器的三次握手;
                                            //但是如果在out.close()之前出現(xiàn)異常服務(wù)器是抓不到任何包的
          out.write(byte[] bb);

          關(guān)于這個(gè)的解釋應(yīng)該是流的緩沖機(jī)制.
          所以正確的寫法應(yīng)該是捕捉到異常之后在catch塊中把流close掉.
          服務(wù)器端開(kāi)發(fā)人員一般會(huì)說(shuō)收不到包所以連接有問(wèn)題,會(huì)把責(zé)任推給客戶端,抓住這個(gè)證據(jù)在跟服務(wù)器端的同事扯皮時(shí)將處于有利的位置,嘎嘎.
          還有就是要多做小實(shí)驗(yàn), 注意代碼要規(guī)范嚴(yán)格.

          發(fā)現(xiàn)的幾個(gè)問(wèn)題:

          1. java.io.IOException: Couldn't write to socket

          2. java.io.IOException: Couldn't read from socket

          CMNET聯(lián)網(wǎng)方案:

          CMWAP聯(lián)網(wǎng)方案:

          移動(dòng)資費(fèi)頁(yè)的處理:

          一個(gè)通用的HTTP連接封裝:

          posted @ 2008-11-04 16:22 LukeW 閱讀(380) | 評(píng)論 (0)編輯 收藏

          主站蜘蛛池模板: 鹿邑县| 东兴市| 堆龙德庆县| 郧西县| 东至县| 五峰| 仙桃市| 稷山县| 闵行区| 卢氏县| 万宁市| 富源县| 武山县| 屏东市| 文水县| 海盐县| 龙游县| 樟树市| 滦南县| 宜兰县| 靖西县| 湖州市| 泽普县| 大竹县| 黄石市| 建平县| 波密县| 武穴市| 伽师县| 台前县| 称多县| 肇源县| 万盛区| 本溪| 六安市| 嘉禾县| 崇左市| 桃源县| 宜宾县| 北碚区| 巴东县|