??xml version="1.0" encoding="utf-8" standalone="yes"?>中文字幕日韩欧美一区二区三区,久久av电影,欧美日韩亚洲一区二区三区在线观看http://www.aygfsteel.com/lukewange-hit1983/presentzh-cnWed, 18 Jun 2025 04:00:26 GMTWed, 18 Jun 2025 04:00:26 GMT60linux讑֤模型http://www.aygfsteel.com/lukewange-hit1983/archive/2008/11/12/240185.htmlLukeWLukeWWed, 12 Nov 2008 15:14:00 GMThttp://www.aygfsteel.com/lukewange-hit1983/archive/2008/11/12/240185.htmlhttp://www.aygfsteel.com/lukewange-hit1983/comments/240185.htmlhttp://www.aygfsteel.com/lukewange-hit1983/archive/2008/11/12/240185.html#Feedback0http://www.aygfsteel.com/lukewange-hit1983/comments/commentRss/240185.htmlhttp://www.aygfsteel.com/lukewange-hit1983/services/trackbacks/240185.html Q. Sysfs文gpȝ
Sysfs文gpȝ是一个类gproc文gpȝ的特D文件系l,用于系l中的设备组l成层次l构Qƈ向用h式程序提供详l的内核数据l构信息。其层目录主要有:
Block目录Q包含所有的块设?br /> Devices目录Q包含系l所有的讑֤QƈҎ讑֤挂接的ȝcdl织成层ơ结?br /> Bus目录Q包含系l中所有的ȝcd
Drivers目录Q包括内怸所有已注册的设备驱动程?br /> Class目录Q系l中的设备类型(如网卡设备,声卡讑֤{)
Q. 内核对象机制关键数据l构
2.1 kobject内核对象
Kobject 是Linux 2.6引入的新的设备管理机Ӟ在内怸由struct kobject表示。通过q个数据l构使所有设备在底层都具有统一的接口,kobject提供基本的对象管理,是构成Linux 2.6讑֤模型的核心结构,它与sysfs文gpȝ紧密兌Q每个在内核中注册的kobject对象都对应于sysfs文gpȝ中的一个目录?br /> Kobjectl构定义为:
struct kobject {
char * k_name;    // 指向讑֤名称的指?/span>
char name[KOBJ_NAME_LEN];   // 讑֤名称
struct kref kref;    // 对象引用计数
struct list_head entry;   // 挂接到所在kset中去的单?/span>
struct kobject * parent; // 指向父对象的指针
struct kset * kset;    // 所属kset的指?/span>
struct kobj_type * ktype;   // 指向其对象类型描q符的指?/span>
struct dentry * dentry; // sysfs文gpȝ中与该对象对应的文g节点路径指针
};

其中的kref域表C对象引用的计敎ͼ内核通过kref实现对象引用计数理Q内核提供两个函数kobject_get()、kobject_put()分别用于增加和减引用计敎ͼ当引用计Cؓ0Ӟ所有该对象使用的资源将被释放?br /> Ktype 域是一个指向kobj_typel构的指针,表示该对象的cd。Kobj_type数据l构包含三个域:一个releaseҎ用于释放kobject? 用的资源Q一个sysfs_ops指针指向sysfs操作表和一个sysfs文gpȝ~省属性列表。Sysfs操作表包括两个函数store()? show()。当用户态读取属性时Qshow()函数被调用,该函数编码指定属性值存入buffer中返回给用户态;而store()函数用于存储用户? 传入的属性倹{?br /> 2.2 kset内核对象集合
Kobject通常通过ksetl织成层ơ化的结构,kset是具有相同类型的kobject的集合,在内怸用kset数据l构表示Q定义ؓQ?br />
struct kset {
struct subsystem * subsys;   // 所在的subsystem的指?/span>
struct kobj_type * ktype;   // 指向该kset对象cd描述W的指针
struct list_head list;      // 用于q接该kset中所有kobject的链表头
struct kobject kobj;    // 嵌入的kobject
struct kset_hotplug_ops * hotplug_ops; // 指向热插拔操作表的指?/span>
};

?含在kset中的所有kobject被组l成一个双向@环链表,list域正是该链表的头。Ktype域指向一个kobj_typel构Q被? kset中的所有kobject׃nQ表C些对象的cd。Kset数据l构q内嵌了一个kobject对象Q由kobj域表C)Q所有属于这个kset 的kobject对象的parent域均指向q个内嵌的对象。此外,ksetq依赖于kobjl护引用计数Qkset的引用计数实际上是内嵌? kobject对象的引用计数?br /> 2.3 subsystem内核对象子系l?br /> Subsystem是一pdkset的集合,描述pȝ中某一 c设备子pȝQ如block_subsys表示所有的块设备,对应于sysfs文gpȝ中的block目录。类似的Qdevices_subsys对应? sysfs中的devices目录Q描q系l中所有的讑֤。Subsystem由struct subsystem数据l构描述Q定义ؓQ?br />
struct subsystem {
struct kset kset;       // 内嵌的kset对象
struct rw_semaphore rwsem; // 互斥讉K信号?/span>
};

?个kset必须属于某个subsystemQ通过讄ksetl构中的subsys域指向指定的subsystem可以一个kset加入到该 subsystem。所有挂接到同一subsystem的kset׃n同一个rwsem信号量,用于同步讉Kkset中的链表?br />
Q. 内核对象机制主要相关函数
针对内核对象不同层次的数据结构,linux 2.6内核定义了一pd操作函数Q定义于lib/kobject.c文g中?br /> 3.1 kobject相关函数
void kobject_init(struct kobject * kobj)Q?/span>// kobject初始化函数。设|kobject引用计数?Qentry域指向自w,其所属kset引用计数加1

int kobject_set_name(struct kobject *kobj, const char *format, )Q?/span>// 讄指定kobject的名U?/span>

void kobject_cleanup(struct kobject * kobj);
void kobject_release(struct kref *kref)Q?/span>// kobject清除函数。当其引用计CؓQ时Q释攑֯象占用的资源?/span>

struct kobject *kobject_get(struct kobject *kobj)Q?/span>// kobj 对象的引用计数加1Q同时返回该对象的指针?/span>

void kobject_put(struct kobject * kobj)Q?/span>// kobj对象的引用计数减1Q如果引用计数降?Q则调用kobject_release()释放该kobject对象?/span>

int kobject_add(struct kobject * kobj)Q?/span>// kobj对象加入Linux讑֤层次。挂接该kobject对象到kset的list链中Q增加父目录各kobject的引用计敎ͼ在其parent指向的目录下创徏文g节点Qƈ启动该类型内核对象的hotplug函数?/span>

int kobject_register(struct kobject * kobj)Q?/span>// kobject注册函数。通过调用kobject_init()初始化kobjQ再调用kobject_add()完成该内核对象的注册?/span>

void kobject_del(struct kobject * kobj)Q?/span>// 从Linux讑֤层次(hierarchy)中删除kobj对象?/span>

void kobject_unregister(struct kobject * kobj)Q?/span>// kobject注销函数。与kobject_register()相反Q它首先调用kobject_del从设备层ơ中删除该对象,再调用kobject_put()减少该对象的引用计数Q如果引用计数降?Q则释放该kobject对象?/span>

3.2 kset相关函数
与kobject 怼Qkset_init()完成指定kset的初始化Qkset_get()和kset_put()分别增加和减kset对象的引用计数? Kset_add()和kset_del()函数分别实现指定keset对象加入讑֤层次和从其中删除Qkset_register()函数完成 kset的注册而kset_unregister()函数则完成kset的注销?br /> 3.3 subsystem相关函数
subsystem有一l完成类似的函数Q分别是Q?br />
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);

Q. 讑֤模型lg
在上q内核对象机制的基础上,Linux的设备模型徏立在几个关键lg的基上,下面我们详细阐述q些lg?br /> 4.1 devices
pȝ中的M讑֤在设备模型中都由一个device对象描述Q其对应的数据结构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对象挂接到全局讑֤链表中,所有的device对象都包含在devices_subsys中,q组l成层次l构。Node域将该对象挂? 到其兄弟对象的链表中Q而bus_list则用于将q接到相同ȝ上的讑֤l织成链表,driver_list则将同一驱动E序理的所有设备组lؓ? 表。此外,children域指向该device对象子对象链表头Qparent域则指向父对象。Device对象q内嵌一个kobject对象Q用于引 用计数管理ƈ通过它实现设备层ơ结构。Driver域指向管理该讑֤的驱动程序对象,而driver_data则是提供l驱动程序的数据。Bus域描q设 备所q接的ȝcd?br /> 内核提供了相应的函数用于操作device对象。其中Device_register()函数一个新的device对象? 入设备模型,q自动在/sys/devices下创Z个对应的目录。Device_unregister()完成相反的操作,注销讑֤对象? Get_device()和put_device()分别增加与减设备对象的引用计数。通常devicel构不单独用,而是包含在更大的l构中作Z 个子l构使用Q比如描qPCI讑֤的struct pci_devQ其中的dev域就是一个device对象?br /> 4.2 drivers
pȝ中的每个驱动E序׃个device_driver对象描述Q对应的数据l构定义为:
struct device_driver {
    
char *name;   // 讑֤驱动E序的名U?/span>
    struct bus_type *bus; // 该驱动所理的设备挂接的ȝcd
    struct kobject kobj;    // 内嵌kobject对象
    struct list_head devices;  // 该驱动所理的设备链表头
    int (*probe)(struct device *dev); // 指向讑֤探测函数Q用于探设备是否可以被该驱动程序管?/span>
int (*remove)(struct device *dev); // 用于删除讑֤的函?/span>
/*
 some fields omitted*/
}Q?/span>

与device l构cMQdevice_driver对象依靠内嵌的kobject对象实现引用计数理和层ơ结构组l。内核提供类似的函数用于操作 device_driver对象Q如get_driver()增加引用计数Qdriver_register()用于向设备模型插入新的driver? 象,同时在sysfs文gpȝ中创建对应的目录。Device_driver()l构q包括几个函敎ͼ用于处理热拔插、即插即用和甉|理事g?br /> 4.3   buses
pȝ中ȝ由struct bus_type描述Q定义ؓQ?br />
struct bus_type {
char   * name; // ȝcd的名U?/span>
struct subsystem subsys; // 与该ȝ相关的subsystem
struct kset drivers; // 所有与该ȝ相关的驱动程序集?/span>
struct kset devices; // 所有挂接在该ȝ上的讑֤集合
struct bus_attribute * bus_attrs; // ȝ属?/span>
struct device_attribute * dev_attrs; // 讑֤属?/span>
struct driver_attribute * drv_attrs;   // 驱动E序属?/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);
}Q?/span>

?个bus_type对象都内嵌一个subsystem对象Qbus_subsys对象理pȝ中所有ȝcd的subsystem对象。每? bus_type对象都对?sys/bus目录下的一个子目录Q如PCIȝcd对应?sys/bus/pci。在每个q样的目录下都存在两个子? 录:devices和driversQ分别对应于bus_typel构中的devices和drivers域)。其中devices子目录描q连接在该? U上的所有设备,而drivers目录则描qC该ȝ兌的所有驱动程序。与device_driver对象cMQbus_typel构q包含几个函? Qmatch()、hotplug(){)处理相应的热插拔、即插即拔和甉|理事g?br /> 4.4 classes
pȝ中的讑֤cȝ struct class描述Q表C某一c设备。所有的class对象都属于class_subsys子系l,对应于sysfs文gpȝ中的/sys/class目录? 每个class对象包括一个class_device链表Q每个class_device对象表示一个逻辑讑֤Qƈ通过struct class_device中的dev域(一个指向struct device的指针)兌一个物理设备。这P一个逻辑讑֤L对应于一个物理设备,但是一个物理设备却可能对应于多个逻辑讑֤。此外,classl构? q包括用于处理热插拔、即插即拔和甉|理事g的函敎ͼq与device对象和driver对象怼?br />

LukeW 2008-11-12 23:14 发表评论
]]>
位运?/title><link>http://www.aygfsteel.com/lukewange-hit1983/archive/2008/11/12/240082.html</link><dc:creator>LukeW</dc:creator><author>LukeW</author><pubDate>Wed, 12 Nov 2008 05:53:00 GMT</pubDate><guid>http://www.aygfsteel.com/lukewange-hit1983/archive/2008/11/12/240082.html</guid><wfw:comment>http://www.aygfsteel.com/lukewange-hit1983/comments/240082.html</wfw:comment><comments>http://www.aygfsteel.com/lukewange-hit1983/archive/2008/11/12/240082.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/lukewange-hit1983/comments/commentRss/240082.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/lukewange-hit1983/services/trackbacks/240082.html</trackback:ping><description><![CDATA[<strong>C中的位运?/strong><br /> 能够q用CQ何整形的数据cd?包括char, int), 无论有没有short, long, unsignedq样的限定词.<br /> <br /> <br /> 位运的应用<br /> <div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 交换指针变量x,y所指向的存储位|处存放的?br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 优势是不需要第三个位置来时存储另一个?br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 但是q个Ҏq没有明昄性能优势,只是一个智力上的消?/span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> inplace_swap(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">x, </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">y)<br /> {<br />  </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">x </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">x </span><span style="color: rgb(0, 0, 0);">^</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">y;<br />  </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">x </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">x </span><span style="color: rgb(0, 0, 0);">^</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">y;<br />  </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">x </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">x </span><span style="color: rgb(0, 0, 0);">^</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">y;<br /> }<br /> </span></div> <br /> <strong>位运常见用?</strong><br /> 实现掩码q算<br /> <br /> <br /> <br /> -----------------------------------<br /> <strong>Java中的位运?/strong><br /> <br /> <br /> <img src ="http://www.aygfsteel.com/lukewange-hit1983/aggbug/240082.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/lukewange-hit1983/" target="_blank">LukeW</a> 2008-11-12 13:53 <a href="http://www.aygfsteel.com/lukewange-hit1983/archive/2008/11/12/240082.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>大端端 -- 各系l及机器的信息表C?/title><link>http://www.aygfsteel.com/lukewange-hit1983/archive/2008/11/12/240053.html</link><dc:creator>LukeW</dc:creator><author>LukeW</author><pubDate>Wed, 12 Nov 2008 03:58:00 GMT</pubDate><guid>http://www.aygfsteel.com/lukewange-hit1983/archive/2008/11/12/240053.html</guid><wfw:comment>http://www.aygfsteel.com/lukewange-hit1983/comments/240053.html</wfw:comment><comments>http://www.aygfsteel.com/lukewange-hit1983/archive/2008/11/12/240053.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/lukewange-hit1983/comments/commentRss/240053.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/lukewange-hit1983/services/trackbacks/240053.html</trackback:ping><description><![CDATA[因ؓ现行的计机都是以八位一个字节ؓ存储单位,那么一?6位的整数,也就是C语言中的short,在内存中可能有两U存储顺序big- <br /> <br /> endian和litte-endian.考虑一个short整数0x3132(0x32是低?0x31是高?,把它赋值给一个short变量,那么它在内存中的存储?br /> <br /> 能有如下两种情况:<br /> 大端字节(Big-endian):<br /> <br /> short变量地址<br />        0x1000                  0x1001<br /> ___________________________________<br /> |                 |<br /> |         0x31    |       0x32<br /> |________________ | ________________<br /> 高位字节在低位字节的前面,也就是高位在内存地址低的一?可以q样C(大端->高位->在前->正常的逻辑序)<br />  <br /> 端字节(little-endian):<br /> <br /> short变量地址<br />        0x1000                  0x1001<br /> _____________________________________<br /> |                 |<br /> |         0x32    |       0x31<br /> |________________ | __________________<br /> 低位字节在高位字节的前面,也就是低位在内存地址低的一?可以q样C(端->低位->在前->与正帔R辑序相反)<br />  <br /> 可以做个实验<br /> 在windows上下如下E序<br /> <div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: rgb(0, 0, 0);">#include </span><span style="color: rgb(0, 0, 0);"><</span><span style="color: rgb(0, 0, 0);">stdio.h</span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);"><br /> #include </span><span style="color: rgb(0, 0, 0);"><</span><span style="color: rgb(0, 0, 0);">assert.h</span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);"><br />  <br /> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> main( </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> )<br /> {<br />         </span><span style="color: rgb(0, 0, 255);">short</span><span style="color: rgb(0, 0, 0);"> test;<br />         FILE</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> fp;<br />         <br />         test </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0x3132</span><span style="color: rgb(0, 0, 0);">;  </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">(31ASIIC码的’1’,32ASIIC码的’2’)</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">        </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> ((fp </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> fopen (</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">c:</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">test.txt</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">wb</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">)) </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> NULL)<br />               assert(</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">);<br />         fwrite(</span><span style="color: rgb(0, 0, 0);">&</span><span style="color: rgb(0, 0, 0);">test, </span><span style="color: rgb(0, 0, 255);">sizeof</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">short</span><span style="color: rgb(0, 0, 0);">), </span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">, fp);<br />         fclose(fp);<br /> }</span></div> <br />     然后在C盘下打开test.txt文g,可以看见内容?1,而test{于0x3132,可以明显的看出来x86的字节顺序是低位在前.如果我们<br /> 把这D同L代码攑ֈ(big-endian)的机器上执行,那么打出来的文g是12.q在本机中用是没有问题?但当你把q个文g从一<br /> 个big- endian机器复制C个little-endian机器上时出现问题了.<br /> <br />     如上qC?我们在big-endian的机器上创徏了这个test文g,把其复制到little-endian的机器上再用freadd一?short?br /> ?我们得到的就不再?x3132而是0x3231?q样d的数据就是错误的,所以在两个字节序不一L机器上传输数据时需要特?br /> 心字节序,理解了字节顺序在可以帮助我们写出UL行更高的代码.<br /> <br /> 正因为有字节序的差?所以在|络传输的时候定义了所有字节顺序相关的数据都用big-endian,BSD的代码中定义了四个宏来处<br /> ?<br /> <div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: rgb(0, 0, 255);">#define</span><span style="color: rgb(0, 0, 0);"> ntohs(n)     </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">|络字节序C机字节顺?nbsp;n代表net, h代表host, s代表short</span><span style="color: rgb(0, 0, 0);"><br /> </span><span style="color: rgb(0, 0, 255);">#define</span><span style="color: rgb(0, 0, 0);"> htons(n)     </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">L字节序到网l字节顺?nbsp;n代表net, h代表host, s代表short</span><span style="color: rgb(0, 0, 0);"><br /> </span><span style="color: rgb(0, 0, 255);">#define</span><span style="color: rgb(0, 0, 0);"> ntohl(n)      </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">|络字节序C机字节顺?nbsp;n代表net, h代表host, s代表 long</span><span style="color: rgb(0, 0, 0);"><br /> </span><span style="color: rgb(0, 0, 255);">#define</span><span style="color: rgb(0, 0, 0);"> htonl(n)      </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">L字节序到网l字节顺?nbsp;n代表net, h代表host, s代表 long</span></div> <br /> 举例说明下这其中一个宏的实?<br /> <div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">#define</span><span style="color: rgb(0, 0, 0);"> sw16(x) "</span><span style="color: rgb(0, 0, 0);"><br />     ((</span><span style="color: rgb(0, 0, 255);">short</span><span style="color: rgb(0, 0, 0);">)( </span><span style="color: rgb(0, 0, 0);">"<br /> </span><span style="color: rgb(0, 0, 0);">        (((</span><span style="color: rgb(0, 0, 255);">short</span><span style="color: rgb(0, 0, 0);">)(x) </span><span style="color: rgb(0, 0, 0);">&</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 255);">short</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">0x00ffU</span><span style="color: rgb(0, 0, 0);">) </span><span style="color: rgb(0, 0, 0);"><<</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">8</span><span style="color: rgb(0, 0, 0);">) </span><span style="color: rgb(0, 0, 0);">|</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"<br /> </span><span style="color: rgb(0, 0, 0);">        (((</span><span style="color: rgb(0, 0, 255);">short</span><span style="color: rgb(0, 0, 0);">)(x) </span><span style="color: rgb(0, 0, 0);">&</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 255);">short</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">0xff00U</span><span style="color: rgb(0, 0, 0);">) </span><span style="color: rgb(0, 0, 0);">>></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">8</span><span style="color: rgb(0, 0, 0);">) ))</span></div> <br /> q里实现的是一个交换两个字节顺?其他几个宏类?<br /> <br /> 我们改写一下上面的E序<br /> <div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: rgb(0, 0, 0);">#include </span><span style="color: rgb(0, 0, 0);"><</span><span style="color: rgb(0, 0, 0);">stdio.h</span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);"><br /> #include </span><span style="color: rgb(0, 0, 0);"><</span><span style="color: rgb(0, 0, 0);">assert.h</span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);"><br /> <br /> </span><span style="color: rgb(0, 0, 255);">#define</span><span style="color: rgb(0, 0, 0);"> sw16(x) "</span><span style="color: rgb(0, 0, 0);"><br />     ((</span><span style="color: rgb(0, 0, 255);">short</span><span style="color: rgb(0, 0, 0);">)( </span><span style="color: rgb(0, 0, 0);">"<br /> </span><span style="color: rgb(0, 0, 0);">        (((</span><span style="color: rgb(0, 0, 255);">short</span><span style="color: rgb(0, 0, 0);">)(x) </span><span style="color: rgb(0, 0, 0);">&</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 255);">short</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">0x00ffU</span><span style="color: rgb(0, 0, 0);">) </span><span style="color: rgb(0, 0, 0);"><<</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">8</span><span style="color: rgb(0, 0, 0);">) </span><span style="color: rgb(0, 0, 0);">|</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"<br /> </span><span style="color: rgb(0, 0, 0);">        (((</span><span style="color: rgb(0, 0, 255);">short</span><span style="color: rgb(0, 0, 0);">)(x) </span><span style="color: rgb(0, 0, 0);">&</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 255);">short</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">0xff00U</span><span style="color: rgb(0, 0, 0);">) </span><span style="color: rgb(0, 0, 0);">>></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">8</span><span style="color: rgb(0, 0, 0);">) ))<br /> <br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 因ؓx86下面是低位在?需要交换一下变成网l字节顺?/span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 255);">#define</span><span style="color: rgb(0, 0, 0);"> htons(x) sw16(x)</span><span style="color: rgb(0, 0, 0);"><br />  <br /> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> main( </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> )<br /> {<br />         </span><span style="color: rgb(0, 0, 255);">short</span><span style="color: rgb(0, 0, 0);"> test;<br />         FILE</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> fp;<br />         <br />         test </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> htons(</span><span style="color: rgb(0, 0, 0);">0x3132</span><span style="color: rgb(0, 0, 0);">); </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">(31ASIIC码的’1’,32ASIIC码的’2’)</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">        </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> ((fp </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> fopen (</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">c:</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">test.txt</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">wb</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">)) </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> NULL)<br />               assert(</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">);<br />         fwrite(</span><span style="color: rgb(0, 0, 0);">&</span><span style="color: rgb(0, 0, 0);">test, </span><span style="color: rgb(0, 0, 255);">sizeof</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">short</span><span style="color: rgb(0, 0, 0);">), </span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">, fp);<br />         fclose(fp);<br /> }</span></div> <br />  <br />     如果在高字节在前的机器上,׃与网l字节顺序一?所以我们什么都不干可以了,只需要把#define htons(x) sw16(x)宏替<br /> <br /> 换ؓ #define htons(x) (x).<br />     一开始我在理解这个问题时,d想ؓ什么其他数据不用交换字节顺?比如说我们write一块buffer到文?最后终于想明白?<br /> <br /> 因ؓ都是unsigned charcd一个字节一个字节的写进?q个序是固定的,不存在字节顺序的问题.<br /> <p><strong><font color="#0000ff">【用函数判断pȝ是Big Endianq是Little Endian?/font></strong><br /> </p> <br /> <div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: rgb(0, 0, 255);">bool</span><span style="color: rgb(0, 0, 0);"> IsBig_Endian()<br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">如果字节序ؓbig-endianQ返回true;<br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">反之?nbsp;  little-endianQ返回false</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">{<br />     unsigned </span><span style="color: rgb(0, 0, 255);">short</span><span style="color: rgb(0, 0, 0);"> test </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0x1122</span><span style="color: rgb(0, 0, 0);">;<br />     </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">( (unsigned </span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">) </span><span style="color: rgb(0, 0, 0);">&</span><span style="color: rgb(0, 0, 0);">test ) </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0x11</span><span style="color: rgb(0, 0, 0);">)<br />        </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> TRUE;<br /> </span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);"><br />     </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> FALSE;<br /> <br /> }</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">IsBig_Endian()<br /> </span></div> <br /> <strong><font color="#0000ff">【打印程序对象的字节表示?/font></strong><font color="#0000ff"><br /> </font> <div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 可在不同q_与硬件架构的机器中测试运行这D代?理解大端表示和小端表C的不同.<br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> q段代码使用强制cd转换规避cdpȝ</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">#incluede </span><span style="color: rgb(0, 0, 0);"><</span><span style="color: rgb(0, 0, 0);">stdio.h</span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);"><br /> <br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 假设每个字节都是非负整数</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">typedef unsigned </span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">byte_pointer;<br /> <br /> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> show_bytes(byte_pointer start, </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> len)<br /> {<br />  </span><span style="color: rgb(0, 0, 255);">for</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">; i </span><span style="color: rgb(0, 0, 0);"><</span><span style="color: rgb(0, 0, 0);"> len; i</span><span style="color: rgb(0, 0, 0);">++</span><span style="color: rgb(0, 0, 0);">)<br />   printf(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> %.2x</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, start[i]);<br />  printf(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br /> }<br /> <br /> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> show_int(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> x)<br /> {<br />  show_bytes((byte_pointer) </span><span style="color: rgb(0, 0, 0);">&</span><span style="color: rgb(0, 0, 0);">x, </span><span style="color: rgb(0, 0, 255);">sizeof</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">));<br /> }<br /> <br /> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> show_float(</span><span style="color: rgb(0, 0, 255);">float</span><span style="color: rgb(0, 0, 0);"> x)<br /> {<br />  show_bytes((byte_pointer) </span><span style="color: rgb(0, 0, 0);">&</span><span style="color: rgb(0, 0, 0);">x, </span><span style="color: rgb(0, 0, 255);">sizeof</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">float</span><span style="color: rgb(0, 0, 0);">));<br /> }<br /> <br /> </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 在用相同编?如ASCII~码)的系l中,字符串字节表C得到的l果一般是相同?所以文本数据比二进制数据具有更强的q_无关?/span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> show_string(</span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">x)<br /> {<br />  show_bytes((byte_pointer) x, strlen(x));<br /> }<br /> <br /> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> show_pointer(</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">x)<br /> {<br />  show_bytes((byte_pointer) </span><span style="color: rgb(0, 0, 0);">&</span><span style="color: rgb(0, 0, 0);">x, </span><span style="color: rgb(0, 0, 255);">sizeof</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">));<br /> }<br /> <br /> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> test_show_bytes(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> val)<br /> {<br />  </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> ival </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> val;<br />  </span><span style="color: rgb(0, 0, 255);">float</span><span style="color: rgb(0, 0, 0);"> fval </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 255);">float</span><span style="color: rgb(0, 0, 0);">)ival;<br />  </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">pval </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">&</span><span style="color: rgb(0, 0, 0);">ival;<br />  <br />  show_int(ival); </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 各个机器因ؓ大端表示和小端表C的不同,从而只是字节顺序不?/span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);"> show_float(fval); </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 各个机器因ؓ大端表示和小端表C的不同,从而只是字节顺序不?/span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);"> show_pointer(pval); </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 指针值是与机器相关的(linux,sun使用4字节地址, 而alpha使用八字节地址)</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">}</span></div> <br /> ---------------------------------------------<br /> 对于如数?2345在int型和float型时的编码表C?br /> <img src ="http://www.aygfsteel.com/lukewange-hit1983/aggbug/240053.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/lukewange-hit1983/" target="_blank">LukeW</a> 2008-11-12 11:58 <a href="http://www.aygfsteel.com/lukewange-hit1983/archive/2008/11/12/240053.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>j2me 联网技术分析ȝhttp://www.aygfsteel.com/lukewange-hit1983/archive/2008/11/04/238629.htmlLukeWLukeWTue, 04 Nov 2008 08:22:00 GMThttp://www.aygfsteel.com/lukewange-hit1983/archive/2008/11/04/238629.htmlhttp://www.aygfsteel.com/lukewange-hit1983/comments/238629.htmlhttp://www.aygfsteel.com/lukewange-hit1983/archive/2008/11/04/238629.html#Feedback0http://www.aygfsteel.com/lukewange-hit1983/comments/commentRss/238629.htmlhttp://www.aygfsteel.com/lukewange-hit1983/services/trackbacks/238629.html基本?

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


------------------------------------------------------------
要注意的问题:
开发中遇到个很头疼的问? 与服务器通信write()数据时报java.io.IOException: Couldn't write to socket.
但是服务器抓不到M? 一开始怀疑是q徏立连接出的问? 实际上服务器抓不到包也有可能是流在没有close的时候就已经报错?
?
conn.open("url");
out = conn.openDataOutputStream();//此时进行与服务器的三次握手;
                                  //但是如果在out.close()之前出现异常服务器是抓不CQ何包?br /> out.write(byte[] bb);

关于q个的解释应该是的~冲机制.
所以正的写法应该是捕捉到异常之后在catch块中把流close?strong>.
服务器端开发h员一般会说收不到包所以连接有问题,会把责Q推给客户?抓住q个证据在跟服务器端的同事扯皮时处于有利的位置,嘎嘎.
q有是要多做小实验, 注意代码要规范严?

发现的几个问?

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

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

CMNET联网Ҏ:

CMWAP联网Ҏ:

Ud资费늚处理:

一个通用的HTTPq接装:



LukeW 2008-11-04 16:22 发表评论
]]>
VIM讄http://www.aygfsteel.com/lukewange-hit1983/archive/2008/11/03/238318.htmlLukeWLukeWMon, 03 Nov 2008 05:02:00 GMThttp://www.aygfsteel.com/lukewange-hit1983/archive/2008/11/03/238318.htmlhttp://www.aygfsteel.com/lukewange-hit1983/comments/238318.htmlhttp://www.aygfsteel.com/lukewange-hit1983/archive/2008/11/03/238318.html#Feedback0http://www.aygfsteel.com/lukewange-hit1983/comments/commentRss/238318.htmlhttp://www.aygfsteel.com/lukewange-hit1983/services/trackbacks/238318.html  
VimQVi Improved) 是一个类gvi 的文本编辑器Q在Vi的基上增加了很多新的Ҏ和功能。Vim以其强大的功能和可定制能?br />
Q成为Linux/Unix环境下开源的最重要的编辑器之一Q另一个是 EmacsQ,被众多开发者所喜爱。笔者此时所用的是最新的7.1版本

?br /> 与大部分其它~辑器不同,q入 Vim 后,~省状态下键入的字Wƈ不会插入到所~辑的文件之中。Vim 的模式(modeQ可以简单地

理解?#8220;状?#8221;Q概念非帔R要。需要知道,Vim 有以下几个模式:
1Q?nbsp;  正常QnormalQ模式,~省的编辑模式;下面如果不加Ҏ说明Q提到的命o都直接在正常模式下输入;M其它模式中都

可以通过键盘上的 Esc 键回到正常模式?br /> 2Q?nbsp;  命oQcommandQ模式,用于执行较长、较复杂的命令;在正常模式下输入“:”Q一般命令)?#8220;/”Q正向搜索)?#8220;?”

Q反向搜索)卛_q入该模式;命o模式下的命o要输入回车键QEnterQ才完成?br /> 3Q?nbsp;  插入QinsertQ模式,输入文本时用;在正常模式下键入“i”QinsertQ或“a”QappendQ即可进入插入模式(也有?br />
外一些命令,?#8220;c”Q也可以q入插入模式Q但q些命o有其它的作用Q?br /> 4Q?nbsp;  可视QvisualQ模式,用于选定文本块;可以在正常模式下输入“v”Q小写)来按字符选定Q输?#8220;V”Q大写)来按行?br />
定,或输?#8220;Ctrl-V”来按方块选定?br /> 5Q?nbsp;  选择QselectQ模式,与普通的 Windows ~辑器较为接q的选择文本块的方式Q在以可视模式和选择模式之一选定文本块之

后,可以使用“Ctrl-G”切换到另一模式——该模式很少?Linux 上用,本文中就不再介绍了?
------------------------------------------
首先 vim ~/.vimrc 打开~辑文g

[转]
   1、VI或VIM的配|文件的路径

    发现/usr/share/vim/vimrc?etc/vim/vimrc指向是同一个文Ӟ即vimrcQؓvi和vim的配|文Ӟ修改q个文g卛_。这个\径在不同的LINUX版本中可能会不同?/p>

    2、配|颜?/p>

    配轩VI和VIM的颜色显C,使它能够高亮度显CZ些特别的单词Q这对编写程序很有用。后来打开文g发现里面其实已经有一行了Q只是用引号注释掉了Q只需 syntax on 所在行前面的引号去掉即可。或者另外独立添加一行:syntax on 也行Q另外编?etc/profile 增加一行alias vi="vim"p了?/p>

    3、设|鼠?/p>

    使用VI~辑文本Ӟ如果想修文g中改d标较q的位置Q这时候想用鼠标定位,可默认情况下Q鼠标是不可用的。如果你想用鼠标,只需另v一行,写上Qset mouse=a 卛_

    4、设|自动羃q?/p>

    默认情况下,VI和VIM都没有羃q的Q每换一行,光标均定位在格Q如果你惌动对齐,请将 set autoindent所在行前面的引号去掉,或者另外添加一行:set autoindent也可。这与配|颜色类伹{这L讄的结果是按回车后新行与上一行自动对齐?/p>

    5、设|tab的羃q量

    如果用python~写E序Q那么行~进量是一个极光要的概念Q同一个块的羃q量必须相同。你可能喜欢在行前加I格来表C羃q,但每ơ必L多次I格 键,如果你喜Ƣ用按TAB键来表示~进Q你可能觉得写的文本或程序不太好看,因ؓ默认情况下,VI和VIM的TAB~进量比较大Q至六Q七个字W)。设 |TAB键羃q量的方法:set shiftwidth=3 你也可以选一 个你自己喜欢的羃q量Q比?Q或4.

----------------------------------------------

首先从视觉方?

W一个要做的是羃q?/strong>,修改你的配置文g_vimrc,在最后加?span style="color: rgb(0, 128, 0);">set cindent,q样p|了c风格的羃q?在这里羃q的大小?span style="color: rgb(51, 153, 102);">shiftwidth的倹{?/p>

W二个要做的是语法高?/strong>Q这个是必须的,在中_vimrc加入syntax enable?/p>

W三个要做的字体的设|?/strong>Q设|一个舒服的字体可以让你~程的时候舒服好多,用editplus的时候我q的ConsolasQ在中我q是用的q种字体Q在_vimrc中加?/p>

if has(”gui_running”)
set guifont=Consolas:h9
endif

表示q行界面的时候就用这U字体?/p>

W四Q设|配色方?/strong>Q可以到点击q儿下蝲Q然后放?span style="color: rgb(0, 128, 0);">$"vimfiles"colorsq个目录下,然后在中加入如下配置

if has(”gui_running”)
set guifont=Consolas:h9
” set color schema
colorscheme
colorscheme_name
endif

colorscheme_nameZ需要设|的配色Ҏ的名U?/span>

接下来是在运行程序中用到的:

W一Q用ctag

中已l带了Ctagsq个E序。尽ctags也可以支持其它编辑器Q但是它正式支持的只?a class="st_tag internal_tag" rel="tag" title="Posts tagged with vim">VIM。Ctags可以帮助E序员很Ҏ地浏览源代码。用下面的命令可以在源代码的根目录下创徏“tags”文gQ?/p>

[/home/brimmer/src]$ ctags -R

“-R”表示递归创徏Q也包括源代码根目录下的所有子目录下的源程序?#8220;tags”文g中包括这些对象的列表Q?/p>

l        ?define定义的宏

l        枚D型变量的?/p>

l        函数的定义、原型和声明

l        名字I间QnamespaceQ?/p>

l        cd定义QtypedefsQ?/p>

l        变量Q包括定义和声明Q?/p>

l        c(classQ、结构(structQ、枚丄型(enumQ和联合QunionQ?/p>

l        cR结构和联合中成员变量或函数

用这?#8220;tags”文g来定位上面这些做了标记的对象Q下面介l一下定位这些对象的ҎQ?/p>

1)        用命令行。在q行的时候加?#8220;-t”参数Q例如:

[/home/brimmer/src]$   -t  foo_bar

q个命o打开定义“foo_bar”Q变量或函数或其它)的文Ӟq把光标定位到这一行?/p>

2)        ?a class="st_tag internal_tag" rel="tag" title="Posts tagged with vim">vim~辑器内?#8220;:ta”命oQ例如:

:ta foo_bar

3)        最方便的方法是把光标移到变量名或函数名上,然后按下“Ctrl-]”。用“Ctrl-o”退回原来的地方?/p>

注意Q运?a class="st_tag internal_tag" rel="tag" title="Posts tagged with vim">vim的时候,必须?#8220;tags”文g所在的目录下运行。否则,q行的时候还要用“:set tags=”命o讑֮“tags”文g的\径,q样才能扑ֈ“tags”文g?/p>

你还可以选择使用taglistq个插gQ这个插件可以在右侧昄函数Q变量等的列?/p>

W二Q改正程序中的错?/strong>

?a class="st_tag internal_tag" rel="tag" title="Posts tagged with vim">VIM~辑器的环境下用“:make”Qmake工具的用已l在我昨天的文章? 提到的云风的几篇文章中详l介l到Q就可以~译E序Q当然其前提是在当前目录下有Makefile文g。运行完“:make”之后Q如果程序中有错误,? 会显C出来。这时候,光标会自动指向第一个出现错误的地方Q而且你还可以看到错误的提C。然后,你就可以Ҏ错误Q而不用手工找到出错的那一行。记住下? 几个有用的命令:

l        “:cl”列出错误

l        “:cn”让光标指向下一个错?/p>

l        “:cp”让光标指向上一个错?/p>

l        “:cnew”从头开?/p>

你甚臛_以让识别出其它编译器而不是gcc的错误提C。这对一些开发嵌入式pȝ的程序员q很有用Q因Z们很可能用的不是gcc而是其它~译器。通过讄“errorformat”的|可以?a class="st_tag internal_tag" rel="tag" title="Posts tagged with vim">VIM识别出编译器的出错提C。因Z同的~译器的出错提示是不同的Q所以如果用的不是gccp重新讄?/p>

errorformat”的值是一个字W串Q它的格式和C语言的scanf的字W串格式相识?/p>

gcc?#8220;errorformat”的gؓQ?f:%l:"%m。其?#8220;%f”表示文g名,“%l”表示行号Q?#8220;%m”表示出错信息?/p>

?#8220;:h errorformat”查看详细的帮助信息?/p>

?span style="color: rgb(0, 128, 0);">“:h quickfix”?#8220;:h make”?#8220;:h makeprg”?#8220;:h errorfile”查看其它的信息?/p>

W三Q用快捷键

下面的这些快捷键对程序员很有帮助Q?br /> 在函CUd光标

[[  转到上一个位于第一列的“{”

]]  转到下一个位于第一列的“{”

{   转到上一个空?/p>

}   转到下一个空?/p>

gd  转到当前光标所指的局部变量的定义

*   转到当前光标所指的单词下一ơ出现的地方

#   转到当前光标所指的单词上一ơ出现的地方
括号的匹?/p>

%   用来q行括受中括号和大括号的匹配。这要看当前光标指向的是什么符号了?/p>

----------------------------------------------

一个ubuntu 下的vimrc配置例子:

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 一般设?br /> """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 讑֮默认解码
set fenc
=utf-8
set fencs
=utf-8,usc-bom,euc-jp,gb18030,gbk,gb2312,cp936

"讑֮搜烦是的高亮昄
set hlsearch

" 不要使用vi的键盘模式,而是vim自己?br /> set nocompatible

" history文g中需要记录的行数
set history=100

" 在处理未保存或只L件的时候,弹出认
set confirm

" 与windows׃n剪脓?br /> set clipboard+=unnamed

" 侦测文gcd
filetype on

" 载入文gcd插g
filetype plugin on

" 为特定文件类型蝲入相关羃q文?br /> filetype indent on

" 保存全局变量
set viminfo+=!

" 带有如下W号的单词不要被换行分割
set iskeyword
+=_,$,@,%,#,-

" 语法高亮
syntax on

" 高亮字符Q让其不?00列限?br /> :highlight OverLength ctermbg=red ctermfg=white guibg=red guifg=white
":match OverLength '"%101v.*'

" 状态行颜色
highlight StatusLine guifg=SlateBlue guibg=Yellow
highlight StatusLineNC guifg=Gray guibg=White

"高亮当前?br /> set cursorline

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 文g讄
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 不要备䆾文gQ根据自己需要取舍)
set nobackup

" 不要生成swap文gQ当buffer被丢弃的时候隐藏它
setlocal noswapfile
set bufhidden=hide

" 字符间插入的像素行数?br /> set linespace=0

" 增强模式中的命o行自动完成操?br /> set wildmenu

" 在状态行上显C光标所在位|的行号和列?br /> set ruler
set rulerformat
=%20(%2*%<%f%=" %m%r" %3l" %c" %p%%%)

" 命o行(在状态行下)的高度,默认?Q这里是2
set cmdheight=2

" 使回格键QbackspaceQ正常处理indent, eol, start{?br /> set backspace=2

" 允许backspace和光标键跨越行边?br /> set whichwrap+=<,>,h,l

" 可以在buffer的Q何地方用鼠标(cMoffice中在工作区双击鼠标定位)
set mouse
=a
set selection
=exclusive
set selectmode
=mouse,key

" 启动的时候不昄那个援助索马里儿童的提示
set shortmess=atI

" 通过使用: commands命oQ告诉我们文件的哪一行被改变q?br /> set report=0

" 不让vim发出讨厌的滴滴声
set noerrorbells

" 在被分割的窗口间昄I白Q便于阅?br /> set fillchars=vert:" ,stl:" ,stlnc:"

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 搜烦和匹?br /> """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 高亮昄匚w的括?br /> set showmatch

" 匚w括号高亮的时_单位是十分之一U)
set matchtime
=5

" 在搜索的时候不忽略大小?br /> set noignorecase

" 不要高亮被搜索的句子QphrasesQ?br /> "set nohlsearch

" 在搜索时Q输入的词句的逐字W高亮(cMfirefox的搜索)
set incsearch

" 输入:set list命o是应该显CZ啥?
set listchars=tab:
"|" ,trail:.,extends:>,precedes:<,eol:$

" 光标Ud到buffer的顶部和底部时保?行距?br /> set scrolloff=3

" 不要闪烁
set novisualbell

" 我的状态行昄的内容(包括文gcd和解码)
set statusline
=%F%m%r%h%w" [FORMAT=%{&ff}]" [TYPE=%Y]" [POS=%l,%v][%p%%]" %{strftime(""%d/%m/%y" -" %H:%M"")}

" L昄状态行
set laststatus=2

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 文本格式和排?br /> """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 自动格式?br /> set formatoptions=tcrqn

" l承前一行的~进方式Q特别适用于多行注?br /> set autoindent

" 为CE序提供自动~进
set smartindent

" 使用C样式的羃q?br /> set cindent

" 制表Wؓ4
set tabstop=4

" l一~进?
set softtabstop
=4
set shiftwidth
=4

" 不要用空g替制表符
set noexpandtab

" 不要换行
"set nowrap

"讄每行80个字W自动换?br /> set textwidth=80

" 在行和段开始处使用制表W?br /> set smarttab

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" CTags的设?br /> """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 按照名称排序
let Tlist_Sort_Type = 
"name"

" 在右侧显C窗?br /> let Tlist_Use_Right_Window = 1

" 压羃方式
let Tlist_Compart_Format = 1

" 如果只有一个bufferQkillH口也kill掉buffer
let Tlist_Exist_OnlyWindow 
= 1

" 不要关闭其他文g的tags
let Tlist_File_Fold_Auto_Close = 0

" 不要昄折叠?br /> let Tlist_Enable_Fold_Column = 1

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Autocommands
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 只在下列文gcd被侦到的时候显CP普通文本文件不昄

if has("autocmd")
   autocmd FileType xml,html,c,cs,java,perl,shell,bash,cpp,python,vim,php,ruby set number
   autocmd FileType xml,html vmap 
<C-o> <ESC>'<i<!--<ESC>o<ESC>'>o-->
   autocmd FileType java,c,cpp,cs vmap 
<C-o> <ESC>'<o/*<ESC>'>o*/
   autocmd FileType html,text,php,vim,c,java,xml,bash,shell,perl,python setlocal textwidth
=80
   autocmd Filetype html,xml,xsl source $VIMRUNTIME
/plugin/closetag.vim
   autocmd BufReadPost 
*
      
" if line("'""") > 0 && line("'""") <= line("$") |
      
"   exe "normal g`""" |
      
" endif
endif 
" has("autocmd")

" C/C++的编译和q行
map <F5> :call CompileRunGcc()<CR>
func! CompileRunGcc()
exec 
"w"
exec 
"!make"
exec 
"! ./%<"
endfunc

" shell scriptq行
map 
<F6> :call CompileRunSH()<CR>
func
! CompileRunSH()
exec 
"w"
exec 
"!chmod a+x %"
exec 
"!./%"
endfunc

" pythonq行
map <F7> :call CompileRunPyhton()<CR>
func! CompileRunPyhton()
exec 
"w"
exec 
"!chmod a+%"
exec 
"!./%"
endfunc

" 能够漂亮地显C?NFO文g
set encoding
=utf-8
function! SetFileEncodings(encodings)
    let b:myfileencodingsbak
=&fileencodings
    let 
&fileencodings=a:encodings
endfunction
function! RestoreFileEncodings()
    let 
&fileencodings=b:myfileencodingsbak
    unlet b:myfileencodingsbak
endfunction

au BufReadPre 
*.nfo call SetFileEncodings('cp437')|set ambiwidth=single
au BufReadPost 
*.nfo call RestoreFileEncodings()

" 高亮昄普通txt文gQ需要txt.vim脚本Q?br /> au BufRead,BufNewFile *  setfiletype txt

" 用空格键来开x?br /> set foldenable
set foldlevel
=0
set foldmethod
=indent
nnoremap 
<space> @=((foldclosed(line('.')) < 0? 'zc' : 'zo')<CR>

" minibufexpl插g的一般设|?br /> let g:miniBufExplMapWindowNavVim = 1
let g:miniBufExplMapWindowNavArrows = 1
let g:miniBufExplMapCTabSwitchBufs = 1
let g:miniBufExplModSelTarget = 1

----------------------
一个相兛_?br /> http://forum.ubuntu.org.cn/viewtopic.php?f=68&t=138212&st=0&sk=t&sd=a

 



LukeW 2008-11-03 13:02 发表评论
]]>
servletqo?/title><link>http://www.aygfsteel.com/lukewange-hit1983/archive/2008/10/28/237119.html</link><dc:creator>LukeW</dc:creator><author>LukeW</author><pubDate>Tue, 28 Oct 2008 06:58:00 GMT</pubDate><guid>http://www.aygfsteel.com/lukewange-hit1983/archive/2008/10/28/237119.html</guid><wfw:comment>http://www.aygfsteel.com/lukewange-hit1983/comments/237119.html</wfw:comment><comments>http://www.aygfsteel.com/lukewange-hit1983/archive/2008/10/28/237119.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/lukewange-hit1983/comments/commentRss/237119.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/lukewange-hit1983/services/trackbacks/237119.html</trackback:ping><description><![CDATA[<h3 title=""><a >servletqo?/a></h3> <div> 1. Servletqo器基 <br /> Servletqo器是Servlet的一U特D用法,主要用来完成一些通用的操作。比如编码的qoQ判断用L登陆状态等{。Servletqo器的适用场合Q? <br /> AQ认证过? <br /> BQ登录和审核qo <br /> CQ图像{换过? <br /> DQ数据压~过? <br /> EQ加密过? <br /> FQo牌过? <br /> GQ资源访问触发事件过? <br /> Servletqo器接口的构成Q? <br /> 所有的Servletqo器类都必d现javax.servlet.Filter接口。这个接口含?个过滤器cdd现的ҎQ? <br /> Ҏ 说明 <br /> init(FilterConfig cfg) q是Servletqo器的初始化方法,性质{同与servlet的initҎ? <br /> doFilter(ServletRequest,ServletResponse,FilterChain) 完成实际的过滤操作,当请求访问过滤器兌的URLӞServlet容器先调用qo器的doFilterҎ。FilterChain参数用于讉K后箋qo? <br /> destroy() Servlet容器在销毁过滤器实例前调用该ҎQ这个方法中可以释放Servletqo器占用的资源。性质{同与servlet的destory()Ҏ? <br /> Servletqo器的创徏步骤Q? <br /> AQ实现javax.servlet.Filter接口的servletc? <br /> BQ实现initҎQ读取过滤器的初始化函数 <br /> CQ实现doFilterҎQ完成对h或过滤的响应 <br /> DQ调用FilterChain接口对象的doFilterҎQ向后箋的过滤器传递请求或响应 <br /> F.在web.xml中配|Filter <br /> 2.使用qo器处理中文问? <br />    当用用户登陆面输入帐号Ӟ如果输入是中文,后台servlet再次输出q个内容Ӟ可能׃是ؕ码,q是因ؓserlvet中默认是以ISO-8859-1格式~码的,如果后台有多个Servlet,多个参数Q这样就不合适,q个问题Q我们可以通过一个过滤器l一解决Q后台的输出都支持中文Q将ISO-8859-1转码为GBK的那D代码! <br /> 3.使用qo器认证用P <br /> 每个qo器也可以配置初始化参敎ͼ可以不需要过滤的地址配置到这个Filter的配|参CQ过滤时Q如果请求地址在配|参CQ则放行Q这? 避免了在程序中编码。每个Filter中初始化Ӟ都可以得到配|对象,在Filter中配|二个不需要过滤的地址Q一个是登陆面Q一个是执行登陆 认证的servletQ? <br /> 4.Servlet监听? <br /> cM与Swing界面应用开发,Servlet也可以创建监听器Q以对Servlet容器Q或Servlet中以象的事g做出反应。Servlet监听器主要有以下几种Q? <br /> ServletRequestListener ,ServletRequestAttributeListenerQ? <br /> HttpSessionActivationListener ,HttpSessionBindingListener , <br /> HttpSessionAttributeListener,HttpSessionListener, <br /> ServletContextListener{等? <br /> q些监听器主要用来监听session,request,applicationq三个对象里存取数据的变化?br /> ----------------------------------------------------------------------------------------------------------------<br /> <br /> <p>servlet API中最重要的一个功能就是能够ؓservlet和JSP面定义qo器。过滤器提供了某些早期服务器所支持的非标准“servlet链接”的一U功能强大且标准的替代品?br />                                                                                                 <br />      qo器是一个程序,它先于与之相关的servlet或JSP面q行在服务器上。过滤器可附加到一个或多个servlet或JSP面上,q且可以查进入这些资源的h信息。在q之后,qo器可以作如下的选择Q?br /> <br /> <font size="+0">1. 以常规的方式调用资源</font>Q即Q调用servlet或JSP面Q?br /> <br /> <font size="+0">2.利用修改q的h信息调用资源?br /> </font><br /> <font size="+0">3. 调用资源Q但在发送响应到客户机前对其q行修改<br /> <br /> </font><font size="+0">4. L该资源调?/font>Q代之以转到其他的资源,q回一个特定的状态代码或生成替换输出?/p> <p>qo器提供了几个重要好处 Q?/p> <p><br />         首先Q它以一U模块化的或可重用的方式装公共的行为。你?0个不同的serlvet或JSP面Q需要压~它们的内容以减下载时间吗Q没问题Q构造一个压~过滤器Q然后将它应用到30个资源上卛_?br /> <br /> 其次Q利用它能够高U访问决{与表现代码相分R这对于JSP特别有h|其中一般希望将几乎整个面集中在表CQ而不是集中在业务逻辑上。例如,? 望阻塞来自某些站点的讉K而不用修改各面Q这些页面受到访问限Ӟ吗?没问题:建立一个访问限制过滤器q把它应用到惌限制讉K的页面上卛_?br /> <br />      最后,qo器你能够对许多不同的资源进行批量性的更改。你有许多现存资源,q些资源除了公司名要更改外其他的保持不变Q能办到么?没问题:构造一个串替换qo器,只要合适就使用它?br /> <br />      但要注意Q过滤器只在与servlet规范2.3版兼容的服务器上有作用。如果你的Web应用需要支持旧版服务器Q就不能使用qo器?br /> <br /> <font size="+0"><span twffan="done">1Q?nbsp;  建立基本qo?/span><br /> <br /> </font>建立一个过滤器涉及下列五个步骤Q?br /> 1Q徏立一个实现Filter接口的类。这个类需要三个方法,分别是:doFilter、init和destroy?br />        doFilterҎ包含主要的过滤代码(见第2步)QinitҎ建立讄操作Q而destroyҎq行清楚?br /> <br /> 2Q在doFilterҎ中放入过滤行为。doFilterҎ的第一个参CؓServletRequest对象。此对象l过滤器提供了对q入的信? Q包括表单数据、cookie和HTTPh_的完全访问。第二个参数为ServletResponseQ通常在简单的qo器中忽略此参数。最后一个参 CؓFilterChainQ如下一步所qͼ此参数用来调用servlet或JSPc?br /> <br /> 3Q调用FilterChain对象的doFilterҎ。Filter接口的doFilterҎ取一个FilterChain对象作ؓ它的一个参 数。在调用此对象的doFilterҎӞȀzM一个相关的qo器。如果没有另一个过滤器与servlet或JSP面兌Q则servlet或JSP 面被激zR?br /> <br /> 4Q对相应的servlet和JSP面注册qo器。在部v描述W文Ӟweb.xmlQ中使用filter和filter-mapping元素?br /> <br /> 5Q禁用激zdservlet。防止用户利用缺省servlet URLl过qo器设|?br /> <br /> 1.1   建立一个实现Filter接口的类<br />       所有过滤器都必d现javax.servlet.Filter。这个接口包含三个方法,分别为doFilter、init和destroy?br /> <br /> public void doFilter(ServletRequset request, <br />                      ServletResponse response,<br />                      FilterChain chain)<br />      thows ServletException, IOException<br /> <br /> 每当调用一个过滤器Q即Q每ơ请求与此过滤器相关的servlet或JSP面Q时Q就执行其doFilterҎ。正是这个方法包含了大部分过滤逻辑? W一个参Cؓ与传入请求有关的ServletRequest。对于简单的qo器,大多数过滤逻辑是基于这个对象的。如果处理HTTPhQƈ且需要访问诸 如getHeader或getCookies{在ServletRequest中无法得到的ҎQ就要把此对象构造成 HttpServletRequest?br /> <br /> W二个参CؓServletResponse。除了在两个情Ş下要使用它以外,通常忽略q个参数。首先,如果希望完全d对相关servlet或JSP? 面的讉K。可调用response.getWriterq直接发送一个响应到客户机。其ơ,如果希望修改相关的servlet或JSP面的输出,可把? 应包含在一个收集所有发送到它的输出的对象中。然后,在调用serlvet或JSP面后,qo器可查输出,如果合适就修改它,之后发送到客户机?br /> <br /> DoFilter的最后一个参CؓFilterChain对象。对此对象调用doFilter以激zMservlet或JSP面相关的下一个过滤器。如果没有另一个相关的qo器,则对doFilter的调用激zservlet或JSP本n?br /> <br /> public void init(FilterConfig config)   thows ServletException<br /> <br /> initҎ只在此过滤器W一ơ初始化时执行,不是每次调用qo器都执行它。对于简单的qo器,可提供此Ҏ的一个空体,但有两个原因需要用init? 首先QFilterConfig对象提供对servlet环境及web.xml文g中指zqo器名的访问。因此,普遍的办法是利用init? FilterConfig对象存放在一个字D中Q以便doFilterҎ能够讉Kservlet环境或过滤器?其次QFilterConfig对象? 有一个getInitParameterҎQ它能够讉K部v描述W文Ӟweb.xmlQ中分配的过滤器初始化参数?br /> <br /> public void destroy( )<br />      大多数过滤器单地为此Ҏ提供一个空体,不过Q可利用它来完成诸如关闭qo器用的文g或数据库q接池等清除d?br /> <span twffan="done"><br /> 1.2   过滤行为放入doFilterҎ</span><br />      doFilterҎ为大多数qo器地关键部分。每当调用一个过滤器Ӟ都要执行doFilter。对于大多数qo器来_doFilter执行的步骤是 Z传入的信息的。因此,可能要利用作为doFilter的第一个参数提供的ServletRequest。这个对象常常构造ؓ HttpServletRequestcdQ以提供对该cȝ更特D方法的讉K?br /> <br /> <font size="+0"><span twffan="done">1.3   调用FilterChain对象的doFilterҎ</span><br /> </font>     Filter接口的doFilterҎ以一个FilterChain对象作ؓ它的W三个参数。在调用该对象的doFilterҎӞȀzM一个相关的 qo器。这个过E一般持l到链中最后一个过滤器为止。在最后一个过滤器调用其FilterChain对象的doFilterҎӞȀzservlet? 面自n?br /> 但是Q链中的Lqo器都可以通过不调用其FilterChain的doFilterҎ中断q个q程。在q样的情况下Q不再调用JSP面的serlvetQƈ且中断此调用q程的过滤器负责输出提供给客户机?br /> <span twffan="done"><br /> 1.4   寚w当的servlet和JSP面注册qo?/span><br />      部v描述W文件的2.3版本引入了两个用于过滤器的元素,分别是:filter和filter-mapping。filter元素向系l注册一个过滤对象,filter-mapping元素指定该过滤对象所应用的URL?br /> <br /> 1.filter元素<br /> filter元素位于部v描述W文Ӟweb.xmlQ的前部Q所有filter-mapping、servlet或servlet-mapping元素之前。filter元素h如下六个可能的子元素Q?br /> <br /> 1?icon   q是一个可选的元素Q它声明IDE能够使用的一个图象文件?br /> 2、filter-name   q是一个必需的元素,它给qo器分配一个选定的名字?br /> 3、display-name   q是一个可选的元素Q它l出IDE使用的短名称?br /> 4?description   q也是一个可选的元素Q它l出IDE的信息,提供文本文档?br /> 5?filter-class   q是一个必需的元素,它指定过滤器实现cȝ完全限定名?br /> 6?init-param   q是一个可选的元素Q它定义可利用FilterConfig的getInitParameterҎd的初始化参数。单个过滤器元素可包含多个init-param元素?br /> <br /> h意,qo是在serlvet规范2.3版中初次引入的。因此,web.xml文g必须使用DTD?.3版本。下面介l一个简单的例子Q?/p> <p>  <font color="#ff6600" size="2"><</font><span twffan="done" style="color: rgb(0, 0, 255);"><font color="#ff6600"><font size="2"><span twffan="done" style="color: rgb(255, 0, 255);">xml version="1.0" encoding="ISO-8859-1"</span><span twffan="done" style="color: rgb(0, 0, 255);">?></span></font></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#ff6600" size="2">    </font></span><span twffan="done" style="color: rgb(0, 0, 255);"><font color="#ff6600"><font size="2"><span twffan="done" style="color: rgb(255, 0, 255);">DOCTYPE web-app PUBLIC<br />         "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />          "http://java.sun.com/dtd/web-app_2_3.dtd"</span><span twffan="done" style="color: rgb(0, 0, 255);">></span></font></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#ff6600" size="2">    </font></span><font color="#ff6600"><font size="2"><span twffan="done" style="color: rgb(0, 0, 255);"><</span><span twffan="done" style="color: rgb(128, 0, 0);">web-app</span><span twffan="done" style="color: rgb(0, 0, 255);">></span></font></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#ff6600" size="2">     </font></span><font color="#ff6600"><font size="2"><span twffan="done" style="color: rgb(0, 0, 255);"><</span><span twffan="done" style="color: rgb(128, 0, 0);">filter</span><span twffan="done" style="color: rgb(0, 0, 255);">></span></font></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#ff6600" size="2">        </font></span><font color="#ff6600"><font size="2"><span twffan="done" style="color: rgb(0, 0, 255);"><</span><span twffan="done" style="color: rgb(128, 0, 0);">filter-name</span><span twffan="done" style="color: rgb(0, 0, 255);">></span><span twffan="done" style="color: rgb(0, 0, 0);">MyFilter</span></font></font><span twffan="done" style="color: rgb(0, 0, 255);"><font color="#ff6600"><font size="2"><span twffan="done" style="color: rgb(128, 0, 0);">filter-name</span><span twffan="done" style="color: rgb(0, 0, 255);">></span></font></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#ff6600" size="2">        </font></span><font color="#ff6600"><font size="2"><span twffan="done" style="color: rgb(0, 0, 255);"><</span><span twffan="done" style="color: rgb(128, 0, 0);">filter-class</span><span twffan="done" style="color: rgb(0, 0, 255);">></span><span twffan="done" style="color: rgb(0, 0, 0);">myPackage.FilterClass</span></font></font><span twffan="done" style="color: rgb(0, 0, 255);"><font color="#ff6600"><font size="2"><span twffan="done" style="color: rgb(128, 0, 0);">filter-class</span><span twffan="done" style="color: rgb(0, 0, 255);">></span></font></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#ff6600" size="2">      </font></span><span twffan="done" style="color: rgb(0, 0, 255);"><font color="#ff6600"><font size="2"><span twffan="done" style="color: rgb(128, 0, 0);">filter</span><span twffan="done" style="color: rgb(0, 0, 255);">></span></font></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#ff6600" size="2">      </font></span><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#ff6600" size="2">      </font></span><font color="#ff6600"><font size="2"><span twffan="done" style="color: rgb(0, 0, 255);"><</span><span twffan="done" style="color: rgb(128, 0, 0);">filter-mapping</span><span twffan="done" style="color: rgb(0, 0, 255);">></span><span twffan="done" style="color: rgb(0, 0, 0);">...</span></font></font><span twffan="done" style="color: rgb(0, 0, 255);"><font color="#ff6600"><font size="2"><span twffan="done" style="color: rgb(128, 0, 0);">filter-mapping</span><span twffan="done" style="color: rgb(0, 0, 255);">></span></font></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#ff6600" size="2">     <</font></span><span twffan="done" style="color: rgb(0, 0, 255);"><font color="#ff6600"><font size="2"><span twffan="done" style="color: rgb(128, 0, 0);">web-app</span><span twffan="done" style="color: rgb(0, 0, 255);">></span></font></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> </span><br /> <span twffan="done"><br /> <font color="#000000">2.filter-mapping元素</font></span><br /> <font color="#000000">    filter-mapping元素位于web.xml文g中filter元素之后serlvet元素之前。它包含如下三个可能的子元素Q?br /> <br /> 1?filter-name   q个必需的元素必M用filter元素声明时给予过滤器的名U相匚w?br /> <br /> 2?url-pattern   此元素声明一个以斜杠Q?Q开始的模式Q它指定qo器应用的URL。所有filter-mapping元素中必L供url-pattern? servlet-name。但不能对单个filter-mapping元素提供多个url-pattern元素V如果希望过滤器适用于多个模式,可重? 整个filter-mapping元素?br /> <br /> 3?servlet-name   此元素给Z个名Uͼ此名U必M利用servlet元素l予servlet或JSP面的名U相匚w。不能给单个filter-mapping元素提供 多个servlet-name元素V如果希望过滤器适合于多个servlet名,可重复这个filter-mapping元素?br /> 下面举一个例子:</font></span></span></span></span></span></span></span></p> <p><span twffan="done" style="color: rgb(0, 0, 0);"><font color="#808080"><span twffan="done" style="color: rgb(0, 0, 0);">xml version</span><span twffan="done" style="color: rgb(0, 0, 0);">=</span><span twffan="done" style="color: rgb(0, 0, 0);">"</span><span twffan="done" style="color: rgb(0, 0, 0);">1.0</span><span twffan="done" style="color: rgb(0, 0, 0);">"</span><span twffan="done" style="color: rgb(0, 0, 0);"> encoding</span><span twffan="done" style="color: rgb(0, 0, 0);">=</span><span twffan="done" style="color: rgb(0, 0, 0);">"</span><span twffan="done" style="color: rgb(0, 0, 0);">ISO-8859-1</span><span twffan="done" style="color: rgb(0, 0, 0);">"</span><span twffan="done" style="color: rgb(0, 0, 0);">?></span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">    </font></span><span twffan="done" style="color: rgb(0, 0, 0);"><font color="#808080"><span twffan="done" style="color: rgb(0, 0, 0);">DOCTYPE web</span><span twffan="done" style="color: rgb(0, 0, 0);">-</span></font><font color="#808080"><span twffan="done" style="color: rgb(0, 0, 0);">app PUBLIC<br />         </span><span twffan="done" style="color: rgb(0, 0, 0);">"</span><span twffan="done" style="color: rgb(0, 0, 0);">-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN</span><span twffan="done" style="color: rgb(0, 0, 0);">"</span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">        </font></span><font color="#808080"><span twffan="done" style="color: rgb(0, 0, 0);">"</span><span twffan="done" style="color: rgb(0, 0, 0);">http://java.sun.com/dtd/web-app_2_3.dtd</span><span twffan="done" style="color: rgb(0, 0, 0);">"</span><span twffan="done" style="color: rgb(0, 0, 0);">></span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">    </font></span><font color="#808080"><span twffan="done" style="color: rgb(0, 0, 0);"><</span><span twffan="done" style="color: rgb(0, 0, 0);">web</span><span twffan="done" style="color: rgb(0, 0, 0);">-</span><span twffan="done" style="color: rgb(0, 0, 0);">app</span><span twffan="done" style="color: rgb(0, 0, 0);">></span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">      </font></span><font color="#808080"><span twffan="done" style="color: rgb(0, 0, 0);"><</span><span twffan="done" style="color: rgb(0, 0, 0);">filter</span><span twffan="done" style="color: rgb(0, 0, 0);">></span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">        </font></span><font color="#808080"><span twffan="done" style="color: rgb(0, 0, 0);"><</span><span twffan="done" style="color: rgb(0, 0, 0);">filter</span><span twffan="done" style="color: rgb(0, 0, 0);">-</span><span twffan="done" style="color: rgb(0, 0, 0);">name</span><span twffan="done" style="color: rgb(0, 0, 0);">></span><span twffan="done" style="color: rgb(0, 0, 0);">MyFilter</span></font><span twffan="done" style="color: rgb(0, 0, 0);"><font color="#808080"><span twffan="done" style="color: rgb(0, 0, 0);">filter</span><span twffan="done" style="color: rgb(0, 0, 0);">-</span><span twffan="done" style="color: rgb(0, 0, 0);">name</span><span twffan="done" style="color: rgb(0, 0, 0);">></span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">        </font></span><font color="#808080"><span twffan="done" style="color: rgb(0, 0, 0);"><</span><span twffan="done" style="color: rgb(0, 0, 0);">filter</span><span twffan="done" style="color: rgb(0, 0, 0);">-</span><span twffan="done" style="color: rgb(0, 0, 255);">class</span><span twffan="done" style="color: rgb(0, 0, 0);">></span><span twffan="done" style="color: rgb(0, 0, 0);">myPackage.FilterClass</span></font><span twffan="done" style="color: rgb(0, 0, 0);"><font color="#808080"><span twffan="done" style="color: rgb(0, 0, 0);">filter</span><span twffan="done" style="color: rgb(0, 0, 0);">-</span><span twffan="done" style="color: rgb(0, 0, 255);">class</span><span twffan="done" style="color: rgb(0, 0, 0);">></span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">      </font></span><span twffan="done" style="color: rgb(0, 0, 0);"><font color="#808080"><span twffan="done" style="color: rgb(0, 0, 0);">filter</span><span twffan="done" style="color: rgb(0, 0, 0);">></span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">      </font></span><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">      </font></span><font color="#808080"><span twffan="done" style="color: rgb(0, 0, 0);"><</span><span twffan="done" style="color: rgb(0, 0, 0);">filter</span><span twffan="done" style="color: rgb(0, 0, 0);">-</span><span twffan="done" style="color: rgb(0, 0, 0);">mapping</span><span twffan="done" style="color: rgb(0, 0, 0);">></span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">        </font></span><font color="#808080"><span twffan="done" style="color: rgb(0, 0, 0);"><</span><span twffan="done" style="color: rgb(0, 0, 0);">filter</span><span twffan="done" style="color: rgb(0, 0, 0);">-</span><span twffan="done" style="color: rgb(0, 0, 0);">name</span><span twffan="done" style="color: rgb(0, 0, 0);">></span><span twffan="done" style="color: rgb(0, 0, 0);">MyFilter</span></font><span twffan="done" style="color: rgb(0, 0, 0);"><font color="#808080"><span twffan="done" style="color: rgb(0, 0, 0);">filter</span><span twffan="done" style="color: rgb(0, 0, 0);">-</span><span twffan="done" style="color: rgb(0, 0, 0);">name</span><span twffan="done" style="color: rgb(0, 0, 0);">></span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">        </font></span><font color="#808080"><span twffan="done" style="color: rgb(0, 0, 0);"><</span><span twffan="done" style="color: rgb(0, 0, 0);">url</span><span twffan="done" style="color: rgb(0, 0, 0);">-</span><span twffan="done" style="color: rgb(0, 0, 0);">pattern</span><span twffan="done" style="color: rgb(0, 0, 0);">>/</span><span twffan="done" style="color: rgb(0, 0, 0);">someDirectory</span><span twffan="done" style="color: rgb(0, 0, 0);">/</span><span twffan="done" style="color: rgb(0, 0, 0);">SomePage.jsp</span></font><span twffan="done" style="color: rgb(0, 0, 0);"><font color="#808080"><span twffan="done" style="color: rgb(0, 0, 0);">url</span><span twffan="done" style="color: rgb(0, 0, 0);">-</span><span twffan="done" style="color: rgb(0, 0, 0);">pattern</span><span twffan="done" style="color: rgb(0, 0, 0);">></span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">      </font></span><span twffan="done" style="color: rgb(0, 0, 0);"><font color="#808080"><span twffan="done" style="color: rgb(0, 0, 0);">filter</span><span twffan="done" style="color: rgb(0, 0, 0);">-</span><span twffan="done" style="color: rgb(0, 0, 0);">mapping</span><span twffan="done" style="color: rgb(0, 0, 0);">></span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">    </font></span><span twffan="done" style="color: rgb(0, 0, 0);"><font color="#808080"><span twffan="done" style="color: rgb(0, 0, 0);">web</span><span twffan="done" style="color: rgb(0, 0, 0);">-</span><span twffan="done" style="color: rgb(0, 0, 0);">app</span><span twffan="done" style="color: rgb(0, 0, 0);">></span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> </span></span></span></span></span></span></span></span></span></span></p> <p><br /> <font color="#000000"><font size="+0"><span twffan="done">1.5   用Ȁzdservlet</span><br /> </font>     在对资源应用qo器时Q可通过指定要应用过滤器的URL模式或servlet名来完成。如果提供servlet名,则此名称必须与web.xml? servlet元素中给出的名称相匹配。如果用应用到一个serlvet的URL模式Q则此模式必M利用web.xml的元素servlet- mapping指定的模式相匚w。但是,多数服务器?#8220;Ȁzdservlet”为servlet体统一个缺省的URLQhttp: //host/WebAppPrefix/servlet/ServletName。需要保证用户不利用q个URL讉KservletQ这样会l过qo? 讄Q?br /> 例如Q假如利用filter和filter-mapping指示名ؓSomeFilter的过滤器应用到名为SomeServlet的servletQ则如下Q?/font></p> <p><span twffan="done" style="color: rgb(0, 0, 255);"><</span><span twffan="done" style="color: rgb(128, 0, 0);">filter</span><span twffan="done" style="color: rgb(0, 0, 255);">></span><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">      </font></span><font color="#808080"><span twffan="done" style="color: rgb(0, 0, 255);"><</span><span twffan="done" style="color: rgb(128, 0, 0);">filter-name</span><span twffan="done" style="color: rgb(0, 0, 255);">></span><span twffan="done" style="color: rgb(0, 0, 0);">SomeFilter</span></font><span twffan="done" style="color: rgb(0, 0, 255);"><font color="#808080"><span twffan="done" style="color: rgb(128, 0, 0);">filter-name</span><span twffan="done" style="color: rgb(0, 0, 255);">></span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">      </font></span><font color="#808080"><span twffan="done" style="color: rgb(0, 0, 255);"><</span><span twffan="done" style="color: rgb(128, 0, 0);">filter-class</span><span twffan="done" style="color: rgb(0, 0, 255);">></span><span twffan="done" style="color: rgb(0, 0, 0);">somePackage.SomeFilterClass</span></font><span twffan="done" style="color: rgb(0, 0, 255);"><font color="#808080"><span twffan="done" style="color: rgb(128, 0, 0);">filter-class</span><span twffan="done" style="color: rgb(0, 0, 255);">></span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">   <</font></span><span twffan="done" style="color: rgb(0, 0, 255);"><font color="#808080"><span twffan="done" style="color: rgb(128, 0, 0);">filter</span><span twffan="done" style="color: rgb(0, 0, 255);">></span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">    </font></span><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">    </font></span><font color="#808080"><span twffan="done" style="color: rgb(0, 0, 255);"><</span><span twffan="done" style="color: rgb(128, 0, 0);">filter-mapping</span><span twffan="done" style="color: rgb(0, 0, 255);">></span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">      </font></span><font color="#808080"><span twffan="done" style="color: rgb(0, 0, 255);"><</span><span twffan="done" style="color: rgb(128, 0, 0);">filter-name</span><span twffan="done" style="color: rgb(0, 0, 255);">></span><span twffan="done" style="color: rgb(0, 0, 0);">SomeFilter</span></font><span twffan="done" style="color: rgb(0, 0, 255);"><font color="#808080"><span twffan="done" style="color: rgb(128, 0, 0);">filter-name</span><span twffan="done" style="color: rgb(0, 0, 255);">></span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">      </font></span><font color="#808080"><span twffan="done" style="color: rgb(0, 0, 255);"><</span><span twffan="done" style="color: rgb(128, 0, 0);">servlet-name</span><span twffan="done" style="color: rgb(0, 0, 255);">></span><span twffan="done" style="color: rgb(0, 0, 0);">SomeServlet</span></font><span twffan="done" style="color: rgb(0, 0, 255);"><font color="#808080"><span twffan="done" style="color: rgb(128, 0, 0);">servlet-name</span><span twffan="done" style="color: rgb(0, 0, 255);">></span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">     <</font></span><span twffan="done" style="color: rgb(0, 0, 255);"><font color="#808080"><span twffan="done" style="color: rgb(128, 0, 0);">filter-mapping</span><span twffan="done" style="color: rgb(0, 0, 255);">></span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> </span></span></span></span></span></span></span></p> <p><br /> <br /> <font color="#000000">接着Q用servlet和servlet-mapping规定URL   http://host/webAppPrefix/Blah 应该调用SomeSerlvetQ如下所C:</font></p> <p><span twffan="done" style="color: rgb(0, 0, 255);"><</span><span twffan="done" style="color: rgb(128, 0, 0);">filter</span><span twffan="done" style="color: rgb(0, 0, 255);">></span><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">      </font></span><font color="#808080"><span twffan="done" style="color: rgb(0, 0, 255);"><</span><span twffan="done" style="color: rgb(128, 0, 0);">filter-name</span><span twffan="done" style="color: rgb(0, 0, 255);">></span><span twffan="done" style="color: rgb(0, 0, 0);">SomeFilter</span></font><span twffan="done" style="color: rgb(0, 0, 255);"><font color="#808080"><span twffan="done" style="color: rgb(128, 0, 0);">filter-name</span><span twffan="done" style="color: rgb(0, 0, 255);">></span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">      </font></span><font color="#808080"><span twffan="done" style="color: rgb(0, 0, 255);"><</span><span twffan="done" style="color: rgb(128, 0, 0);">filter-class</span><span twffan="done" style="color: rgb(0, 0, 255);">></span><span twffan="done" style="color: rgb(0, 0, 0);">somePackage.SomeFilterClass</span></font><span twffan="done" style="color: rgb(0, 0, 255);"><font color="#808080"><span twffan="done" style="color: rgb(128, 0, 0);">filter-class</span><span twffan="done" style="color: rgb(0, 0, 255);">></span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">    </font></span><span twffan="done" style="color: rgb(0, 0, 255);"><font color="#808080"><span twffan="done" style="color: rgb(128, 0, 0);">filter</span><span twffan="done" style="color: rgb(0, 0, 255);">></span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">    </font></span><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">    </font></span><font color="#808080"><span twffan="done" style="color: rgb(0, 0, 255);"><</span><span twffan="done" style="color: rgb(128, 0, 0);">filter-mapping</span><span twffan="done" style="color: rgb(0, 0, 255);">></span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">      </font></span><font color="#808080"><span twffan="done" style="color: rgb(0, 0, 255);"><</span><span twffan="done" style="color: rgb(128, 0, 0);">filter-name</span><span twffan="done" style="color: rgb(0, 0, 255);">></span><span twffan="done" style="color: rgb(0, 0, 0);">SomeFilter</span></font><span twffan="done" style="color: rgb(0, 0, 255);"><font color="#808080"><span twffan="done" style="color: rgb(128, 0, 0);">filter-name</span><span twffan="done" style="color: rgb(0, 0, 255);">></span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">      </font></span><font color="#808080"><span twffan="done" style="color: rgb(0, 0, 255);"><</span><span twffan="done" style="color: rgb(128, 0, 0);">servlet-name</span><span twffan="done" style="color: rgb(0, 0, 255);"><font size="+0">>/Blah</font></span></font><span twffan="done" style="color: rgb(0, 0, 255);"><font color="#808080"><span twffan="done" style="color: rgb(128, 0, 0);">servlet-name</span><span twffan="done" style="color: rgb(0, 0, 255);">></span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">     <</font></span><span twffan="done" style="color: rgb(0, 0, 255);"><font color="#808080"><span twffan="done" style="color: rgb(128, 0, 0);">filter-mapping</span><span twffan="done" style="color: rgb(0, 0, 255);">></span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> </span></span></span></span></span></span></span></p> <p><br /> <br /> <font color="#000000">现在Q在客户Z用URL   http://host/webAppPrefix/Blah 时就会调用过滤器。过滤器不应用到<br /> http://host/webAppPrefix/servlet/SomePackage.SomeServletClass?br /> 管有关闭激zd的服务器专用Ҏ。但是,可移植最强的Ҏ旉新映Web应用钟的/servlet模式Q这样所有包含此模式的请求被送到相同? servlet中。ؓ了重新映此模式Q首先应该徏立一个简单的servletQ它打印一条错误消息,或重定向用户到顶层页。然后,使用servlet? servlet-mapping元素发送包?servlet模式的请求到该servlet。程序清?-1l出了一个简短的例子?br /> <br /> E序清单9-1 web.xmlQ重定向~省servlet URL的摘录)</font></p> <p> <span twffan="done" style="color: rgb(0, 0, 255);"><font color="#808080"><span twffan="done" style="color: rgb(255, 0, 255);">xml version="1.0" encoding="ISO-8859-1"</span><span twffan="done" style="color: rgb(0, 0, 255);">?></span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">    </font></span><span twffan="done" style="color: rgb(0, 0, 255);"><font color="#808080"><span twffan="done" style="color: rgb(255, 0, 255);">DOCTYPE web-app PUBLIC<br />          "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />          "http://java.sun.com/dtd/web-app_2_3.dtd"</span><span twffan="done" style="color: rgb(0, 0, 255);">></span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">    </font></span><font color="#808080"><span twffan="done" style="color: rgb(0, 0, 255);"><</span><span twffan="done" style="color: rgb(128, 0, 0);">web-app</span><span twffan="done" style="color: rgb(0, 0, 255);">></span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">    </font></span><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">    </font></span><font color="#808080"><span twffan="done" style="color: rgb(0, 0, 255);"><</span><span twffan="done" style="color: rgb(128, 0, 0);">servlet</span><span twffan="done" style="color: rgb(0, 0, 255);">></span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">      </font></span><font color="#808080"><span twffan="done" style="color: rgb(0, 0, 255);"><</span><span twffan="done" style="color: rgb(128, 0, 0);">servlet-name</span><span twffan="done" style="color: rgb(0, 0, 255);">></span><span twffan="done" style="color: rgb(0, 0, 0);">Error</span></font><span twffan="done" style="color: rgb(0, 0, 255);"><font color="#808080"><span twffan="done" style="color: rgb(128, 0, 0);">servlet-name</span><span twffan="done" style="color: rgb(0, 0, 255);">></span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">      </font></span><font color="#808080"><span twffan="done" style="color: rgb(0, 0, 255);"><</span><span twffan="done" style="color: rgb(128, 0, 0);">servlet-class</span><span twffan="done" style="color: rgb(0, 0, 255);">></span><span twffan="done" style="color: rgb(0, 0, 0);">somePackage.ErrorServlet</span></font><span twffan="done" style="color: rgb(0, 0, 255);"><font color="#808080"><span twffan="done" style="color: rgb(128, 0, 0);">servlet-class</span><span twffan="done" style="color: rgb(0, 0, 255);">></span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">    </font></span><span twffan="done" style="color: rgb(0, 0, 255);"><font color="#808080"><span twffan="done" style="color: rgb(128, 0, 0);">servlet</span><span twffan="done" style="color: rgb(0, 0, 255);">></span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">    </font></span><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">    </font></span><font color="#808080"><span twffan="done" style="color: rgb(0, 0, 255);"><</span><span twffan="done" style="color: rgb(128, 0, 0);">servlet-mapping</span><span twffan="done" style="color: rgb(0, 0, 255);">></span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">      </font></span><font color="#808080"><span twffan="done" style="color: rgb(0, 0, 255);"><</span><span twffan="done" style="color: rgb(128, 0, 0);">servlet-name</span><span twffan="done" style="color: rgb(0, 0, 255);">></span><span twffan="done" style="color: rgb(0, 0, 0);">Error</span></font><span twffan="done" style="color: rgb(0, 0, 255);"><font color="#808080"><span twffan="done" style="color: rgb(128, 0, 0);">servlet-name</span><span twffan="done" style="color: rgb(0, 0, 255);">></span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">      </font></span><font color="#808080"><span twffan="done" style="color: rgb(0, 0, 255);"><</span><span twffan="done" style="color: rgb(128, 0, 0);">url-pattern</span><span twffan="done" style="color: rgb(0, 0, 255);">></span><span twffan="done" style="color: rgb(0, 0, 0);">/servlet/*</span></font><span twffan="done" style="color: rgb(0, 0, 255);"><font color="#808080"><span twffan="done" style="color: rgb(128, 0, 0);">url-pattern</span><span twffan="done" style="color: rgb(0, 0, 255);">></span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">    </font></span><span twffan="done" style="color: rgb(0, 0, 255);"><font color="#808080"><span twffan="done" style="color: rgb(128, 0, 0);">servlet-mapping</span><span twffan="done" style="color: rgb(0, 0, 255);">></span></font><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">    </font></span><span twffan="done" style="color: rgb(0, 0, 0);"><br /> <font color="#808080">    <</font></span><span twffan="done" style="color: rgb(0, 0, 255);"><font color="#808080"><span twffan="done" style="color: rgb(128, 0, 0);">web-app</span><span twffan="done" style="color: rgb(0, 0, 255);">></span></font></span></span></span></span></span></span></span></span></span></p> -------------------------------------------------------------------------------------------<br /> <strong><span style="color: rgb(255, 8, 8);">解决q</span></strong><br /> <br /> <p>web.xml加配|?/p> <p><!--   qo?--><br />  <filter><br />   <filter-name>Filter</filter-name><br />   <filter-class><br />    com.util.EncodingFilter<!-- qo器类 --><br />   </filter-class><br />   <init-param><br />    <param-name>Encoding</param-name><br />    <param-value>gb2312</param-value><br />   </init-param><br />  </filter><br />  <filter-mapping><br />   <filter-name>Filter</filter-name><br />   <url-pattern>/*</url-pattern><br />  </filter-mapping></p> <p>EncodingFilter.java</p> <p>package com.hibernate.util;</p> <p>import java.io.IOException;</p> <p>import javax.servlet.Filter;<br /> import javax.servlet.FilterChain;<br /> import javax.servlet.FilterConfig;<br /> import javax.servlet.ServletException;<br /> import javax.servlet.ServletRequest;<br /> import javax.servlet.ServletResponse;</p> <p>public class EncodingFilter implements Filter {<br />  protected FilterConfig config;</p> <p> protected String Encoding = null;</p> <p> public void init(FilterConfig config) throws ServletException {</p> <p>  this.config = config;<br />   this.Encoding = config.getInitParameter("Encoding");</p> <p> }</p> <p> public void doFilter(ServletRequest request, ServletResponse response,<br />    FilterChain chain) throws IOException, ServletException {</p> <p>  if (request.getCharacterEncoding() == null) {<br />    if (Encoding != null) {<br />     request.setCharacterEncoding(Encoding);<br />     response.setCharacterEncoding(Encoding);<br />    }<br />   }<br />   chain.doFilter(request,response);<br />  }<br />  public void destroy() {}<br /> }</p> <p>OK!!!</p> ----------------------------------------------------------------------------------------------------<br /> <br /> 很简单的qo器,是Z记录一个url的请求时?filter:<br /> <ol start="1"> <li>package com.javaeye.wqf;  </li> <li>import javax.servlet.*;  </li> <li>  </li> <li>public class CounterFilter implements Filter {  </li> <li>    public void doFilter(ServletRequest request, ServletResponse response,  </li> <li>            FilterChain chain) throws IOException, ServletException {  </li> <li>        long start = System.currentTimeMillis();  </li> <li>        System.out.println("Filter start at "+start);  </li> <li>        chain.doFilter(request, response);  </li> <li>        long end = System.currentTimeMillis();  </li> <li>        System.out.println("Filter end at "+end);  </li> <li>    }  <br /> </li> <li>}  <br /> </li> </ol> <br /> <br /> <ol start="1"> <li><filter>  </li> <li>    <filter-name>test</filter-name>  </li> <li>    <filter-class>com.javaeye.wqf.CounterFilter</filter-class>  </li> <li></filter>  </li> <li>  </li> <li><filter-mapping>  </li> <li>    <filter-name>test</filter-name>  </li> <li>    <url-pattern>/*</url-pattern>  </li> <li></filter-mapping>  <br /> </li> </ol> 一般情况下是没什么问题,但是当我下蝲一个稍微大的文件时Q蟩出确认窗口,如果选择的是cancelQ? <br /> ׃发现filterq没有返回,也就是说 <br /> <ol start="1"> <li>System.out.println("Filter end at "+end);  <br /> </li> </ol> q没有执? 原因?<br /> <br /> chain.doFilter(request, response);   <br /> 执行到这里时会从q里调用剩下的filter和servletQ所以这个调用将会是一个很长的q程? <br /> 在这个调用里Q将会完全通过request和resonseL作连接,取得/发送数据,如果q接出现异常Q将直接弹出Exception <br /> 你的代码里没有捕获异常,所以如果出现异常,chain.doFilter后面的就不会执行? <br /> 可以把chain.doFilter攑ֈtry finallyl构中,保证后箋会被执行 <br /> <br /> <br /> <br /> <br /> </div> <img src ="http://www.aygfsteel.com/lukewange-hit1983/aggbug/237119.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/lukewange-hit1983/" target="_blank">LukeW</a> 2008-10-28 14:58 <a href="http://www.aygfsteel.com/lukewange-hit1983/archive/2008/10/28/237119.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Android应用E序剖析http://www.aygfsteel.com/lukewange-hit1983/archive/2008/10/07/232943.htmlLukeWLukeWTue, 07 Oct 2008 08:22:00 GMThttp://www.aygfsteel.com/lukewange-hit1983/archive/2008/10/07/232943.htmlhttp://www.aygfsteel.com/lukewange-hit1983/comments/232943.htmlhttp://www.aygfsteel.com/lukewange-hit1983/archive/2008/10/07/232943.html#Feedback0http://www.aygfsteel.com/lukewange-hit1983/comments/commentRss/232943.htmlhttp://www.aygfsteel.com/lukewange-hit1983/services/trackbacks/232943.htmlAnatomy of an Android Application

There are four building blocks to an Android application:
  • Activity
  • Intent Receiver
  • Service
  • Content Provider

Not every application needs to have all four, but your application will be written with some combination of these.

Once you have decided what components you need for your application, you should list them in a file called AndroidManifest.xml. This is an XML file where you declare the components of your application and what their capabilities and requirements are. See the Android manifest file documentation for complete details.

Activity
Activities are the most common of the four Android building blocks. An activity is usually a single screen in your application. Each activity is implemented as a single class that extends the Activity base class. Your class will display a user interface composed of Views and respond to events. Most applications consist of multiple screens. For example, a text messaging application might have one screen that shows a list of contacts to send messages to, a second screen to write the message to the chosen contact, and other screens to review old messages or change settings. Each of these screens would be implemented as an activity. Moving to another screen is accomplished by a starting a new activity. In some cases an activity may return a value to the previous activity -- for example an activity that lets the user pick a photo would return the chosen photo to the caller.

When a new screen opens, the previous screen is paused and put onto a history stack. The user can navigate backward through previously opened screens in the history. Screens can also choose to be removed from the history stack when it would be inappropriate for them to remain. Android retains history stacks for each application launched from the home screen.

Intent and Intent Filters
Android uses a special class called an Intent to move from screen to screen. An intent describes what an application wants done. The two most important parts of the intent data structure are the action and the data to act upon. Typical values for action are MAIN (the front door of the activity), VIEW, PICK, EDIT, etc. The data is expressed as a URI. For example, to view contact information for a person, you would create an intent with the VIEW action and the data set to a URI representing that person.

There is a related class called an IntentFilter. While an intent is effectively a request to do something, an intent filter is a description of what intents an activity (or intent receiver, see below) is capable of handling. An activity that is able to display contact information for a person would publish an IntentFilter that said that it knows how to handle the action VIEW when applied to data representing a person. Activities publish their IntentFilters in the AndroidManifest.xml file.

Navigating from screen to screen is accomplished by resolving intents. To navigate forward, an activity calls startActivity(myIntent). The system then looks at the intent filters for all installed applications and picks the activity whose intent filters best matches myIntent. The new activity is informed of the intent, which causes it to be launched. The process of resolving intents happens at run time when startActivity is called, which offers two key benefits:

* Activities can reuse functionality from other components simply by making a request in the form of an Intent
* Activities can be replaced at any time by a new Activity with an equivalent IntentFilter


Intent Receiver
You can use an IntentReceiver when you want code in your application to execute in reaction to an external event, for example, when the phone rings, or when the data network is available, or when it's midnight. Intent receivers do not display a UI, although they may use the NotificationManager to alert the user if something interesting has happened. Intent receivers are registered in AndroidManifest.xml, but you can also register them from code using Context.registerReceiver(). Your application does not have to be running for its intent receivers to be called; the system will start your application, if necessary, when an intent receiver is triggered. Applications can also send their own intent broadcasts to others with Context.broadcastIntent().
Service

A Service is code that is long-lived and runs without a UI. A good example of this is a media player playing songs from a play list. In a media player application, there would probably be one or more activities that allow the user to choose songs and start playing them. However, the music playback itself should not be handled by an activity because the user will expect the music to keep playing even after navigating to a new screen. In this case, the media player activity could start a service using Context.startService() to to run in the background to keep the music going. The system will then keep the music playback service running until it has finished. (You can learn more about the priority given to services in the system by reading Lifecycle of an Android Application.) Note that you can connect to a service (and start it if it's not already running) with the Context.bindService() method. When connected to a service, you can communicate with it through an interface exposed by the service. For the music service, this might allow you to pause, rewind, etc.

Content Provider
Applications can store their data in files, an SQLite database, or any other mechanism that makes sense. A content provider, however, is useful if you want your application's data to be shared with other applications. A content provider is a class that implements a standard set of methods to let other applications store and retrieve the type of data that is handled by that content provider.

To get more details on content providers, see Accessing Content Providers.

LukeW 2008-10-07 16:22 发表评论
]]>
HTTP协议中的Tranfer-EncodingQchunked~码解析http://www.aygfsteel.com/lukewange-hit1983/archive/2008/09/24/230952.htmlLukeWLukeWWed, 24 Sep 2008 10:03:00 GMThttp://www.aygfsteel.com/lukewange-hit1983/archive/2008/09/24/230952.htmlhttp://www.aygfsteel.com/lukewange-hit1983/comments/230952.htmlhttp://www.aygfsteel.com/lukewange-hit1983/archive/2008/09/24/230952.html#Feedback2http://www.aygfsteel.com/lukewange-hit1983/comments/commentRss/230952.htmlhttp://www.aygfsteel.com/lukewange-hit1983/services/trackbacks/230952.html     通常情况下,Transfer-Encoding域的值应当ؓchunked,表明采用chunked~码方式来进行报文体的传输。chunked~码是HTTP/1.1 RFC里定义的一U编码方式,因此所有的HTTP/1.1应用都应当支持此方式?br />     chunked~码的基本方法是大块数据分解成多块数据,每块都可以自指定长度Q其具体格式如下QBNF文法Q?
    Chunked-Body   = *chunk            //0臛_个chunk
                     last-chunk         //最后一个chunk
                     trailer            //N
                     CRLF               //l束标记W?br />
   chunk          = chunk-size [ chunk-extension ] CRLF  
                        chunk-data CRLF
   chunk-size     = 1*HEX
   last-chunk     = 1*("0") [ chunk-extension ] CRLF

   chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
   chunk-ext-name = token
   chunk-ext-val  = token | quoted-string
   chunk-data     = chunk-size(OCTET)
   trailer        = *(entity-header CRLF)     
   
    解释Q?br />     Chunked-Body表示l过chunked~码后的报文体。报文体可以分ؓchunk, last-chunkQtrailer和结束符四部分。chunk的数量在报文体中最可以ؓ0Q无上限Q每个chunk的长度是自指定的Q即Qv始的? 据必然是16q制数字的字W串Q代表后面chunk-data的长度(字节敎ͼ。这?6q制的字W串W一个字W如果是“0”Q则表示chunk- size?Q该chunk为last-chunk,无chunk-data部分。可选的chunk-extension由通信双方自行定Q如果接收? 不理解它的意义,可以忽略?br />     trailer是附加的在尾部的额外头域Q通常包含一些元数据Qmetadata, meta means "about information"Q,q些头域可以在解码后附加在现有头域之后?br />     实例分析Q?br />     下面分析用ethereal抓包使用Firefox与某|站通信的结果(从头域结束符后开始)Q?br /> Address  0..........................  f
000c0                                31
000d0    66 66 63 0d 0a ...............   // ASCII?1ffc"r"n, chunk-data数据起始地址?00d5
         很明显,“1ffc”为第一个chunk的chunk-size,转换为int?188.׃1ffc后马上就?br />          CRLF,因此没有chunk-extension.chunk-data的v始地址?00d5, 计算可知下一块chunk的v?br />          地址?00d5+1ffc + 2=020d3,如下Q?br /> 020d0    .. 0d 0a 31 66 66 63 0d 0a .... // ASCII?"r"n1ffc"r"n
         前一?d0a是上一个chunk的结束标记符Q后一?d0a则是chunk-size和chunk-data的分隔符?br />          此块chunk的长度同样ؓ8188, 依次cLQ直到最后一?br /> 100e0                          0d 0a 31
100f0    65 61 39 0d 0a......            //ASII码:"r"n"1ea9"r"n
         此块长度?x1ea9 = 7849, 下一块v始ؓ100f5 + 1ea9 + 2 = 11fa0,如下Q?br /> 100a0    30 0d 0a 0d 0a                  //ASCII码:0"r"n"r"n
         “0”说明当前chunk为last-chunk, W一?d 0a为chunkl束W。第二个0d0a说明没有trailer部分Q整个Chunk-bodyl束?br />     解码程Q?br />     对chunked~码q行解码的目的是分块的chunk-data整合恢复成一块作为报文体Q同时记录此块体的长度?br />     RFC2616中附带的解码程如下Q?伪代码)
    length := 0         //长度计数器置0
    read chunk-size, chunk-extension (if any) and CRLF      //dchunk-size, chunk-extension
                                                          //和CRLF
    while(chunk-size > 0 )   {            //表明不是last-chunk
          read chunk-data and CRLF            //读chunk-size大小的chunk-data,skip CRLF
          append chunk-data to entity-body     //此块chunk-dataq加到entity-body?br />           read chunk-size and CRLF          //d新chunk的chunk-size ?CRLF
    }
    read entity-header      //entity-header的格式ؓname:valueCRLF,如果为空卛_有CRLF
    while Qentity-header not empty)   //卻I不是只有CRLF的空?br />     {
       append entity-header to existing header fields
       read entity-header
    }
    Content-Length:=length      //整个解码流E结束后计算得到的新报文体length
                                 //作ؓContent-Length域的值写入报文中
    Remove "chunked" from Transfer-Encoding  //同时从Transfer-Encoding中域值去除chunkedq个标记
    length最后的值实际ؓ所有chunk的chunk-size之和Q在上面的抓包实例中Q一共有八块chunk-size?x1ffc(8188)的chunk,剩下一块ؓ0x1ea9(7849),加v来一?3353字节?br />     注:对于上面例子中前几个chunk的大都?188,可能是因?"1ffc" 4字节Q?"r"n"2字节Q加上块一?"r"n"2字节一?字节Q因此一个chunk整体?196,正好可能是发送端一ơTCP发送的~存大小?

LukeW 2008-09-24 18:03 发表评论
]]>
HTTP Connectionshttp://www.aygfsteel.com/lukewange-hit1983/archive/2008/09/24/230951.htmlLukeWLukeWWed, 24 Sep 2008 10:01:00 GMThttp://www.aygfsteel.com/lukewange-hit1983/archive/2008/09/24/230951.htmlhttp://www.aygfsteel.com/lukewange-hit1983/comments/230951.htmlhttp://www.aygfsteel.com/lukewange-hit1983/archive/2008/09/24/230951.html#Feedback1http://www.aygfsteel.com/lukewange-hit1983/comments/commentRss/230951.htmlhttp://www.aygfsteel.com/lukewange-hit1983/services/trackbacks/230951.htmlHTTP Connections
最q初涉网l编E,分析了下HTTP协议Q下面ؓW一关于HTTPq接控制斚w的学习日志,主要参考RFC2616Q肯定有疏漏之处Q还望指出?br /> HTTP协议是位于传输层之上的应用层协议Q其|络层基通常是TCP协议。TCP协议是面向连接和的Q因此连接的状态和控制对于HTTP协议而言相当重要。同ӞHTTP是基于报文的Q因此如何确定报文长度也是协议中比较重要的一炏V?br /> Persistent Connections持久q接
目的
    在用持久连接前QHTTP协议规定取每个URL资源都需要用单独的一个TCPq接Q这增加了HTTP服务端的负蝲Q引起互联网拥塞。例如内嵌图片以及其他类似数据的使用要求一个客L在很短时间内向同一个服务端发v多个h?br /> 使用持久q接的优?
减少TCPq接数量
在一个连接上实现HTTPh和应{的水Q即允许客户端发出多个请求,而不必在接收到前一h的应{后才发Z一hQ极大减时间消?br /> 后箋h延迟减少Q无需再在TCP握手上耗时
可以更加优雅地实现HTTP协议Q由于持l连接的存在无需报告错误后无需关闭q接Q因此客L可用最新的协议Ҏ发求,如果接收到表C错误的应答Q则换用更旧的语义?br />
M描述
HTTP/1.1和之前版本的显著区别是HTTP/1.1默认使用持久q接。即Q除非服务端在应{中明确指出Q客L应当假定服务端会l持一个持久连接,即从服务端收到的应{是报告错误?br /> ? 久连接对关闭TCPq接的行为提供信号量机制支持。这个信号量是在HTTP头中的Connection域设|,注意Client向Proxy发出h时该 域可能被Proxy-Connection域替换。一旦close信号被表明,客户端绝不能再通过该连接发送更多的h?br />
协商(Negotiation)
HTTP/1.1 服务端可以假定HTTP/1.1客户端会l持持久q接Q除非请求中Connection域的值是"close".同样的,如果服务端打在送出应答后立? 关闭q接Q它应当在应{中包含同样的Connection域?TCPq接关闭是双向的,此时TCPq入半关闭状?
同样的,HTTP/1.1客户端可以期望连接是持久的,除非如前所q收到表C接关闭的应答。当Ӟ也可以主动发Z个包含Connection:close的请求以表明l止q接?br /> 无论客户端还是服务端发出的报文包含Connection:closeQ则该请求均接上的最后一个请?服务端发出此应答后关闭,因此不可能接收更多的h)
报文传输长度
    Z证持久性,q接上的报文都必L一个自定义的报文传输长?否则必须通过q接的关闭表C报文结束,因ؓTCPq接是面向流?Q确定的规则按优先由高C排列如下Q?br />     报文传输长度指报文中出现的报文体的长?卻I不包括头长度Q因为报文头的结束可通过q箋两个CRLF定Q?br /> 1.Ml不能包含报文体(?xx,204,304)的应{消息L以头域后的第一个空行结?无视头中所有的entitycd域的讄Q包括Content-Length域?br /> 2.Transfer-Encoding域出玎ͼ其gؓ?identify"以外的其他|则用"chunked"传输~码方式定传输长度Q具体方式留待下分析?br /> 3.Content- Length域出玎ͼ且Transfer-Encoding域未出现(出现则忽略Content-Length?。Content-Length域的? 为十q制数的字节序,如Content-LengthQ?234Q则1???是分别作Z个octet传输的,因此需要atoi转换成数倹{?br /> 4.如果报文使用?multipart/byteranges"的媒体类型,且没对传输长度做前面的指明,则这U自分割的媒体类型定义了传输长度。具体参见Range头域的说明?br /> 5.服务端关闭连?此方法不可用于客L发出的请求报文,因ؓ客户端关闭连接则使得服务端无法发送应{?.
    Z持和HTTP/1.0的兼Ҏ? 包含报文体的HTTP/1.1h必须包含合法的Content-Length头域,除非明确知道服务端是HTTP/1.1兼容?如果h包含消息? 而没有Content-Length?那么如果服务端无法确定消息长度时,它会q回400(无效h),或者坚持获取合法Content-Length 而返?11(要求包含长度).

    所有接收实体的HTTP/1.1应用E序必须接受"chunked"传输~码, q样允许当报文长度无法预先确定时可以q用此机制获取报文长?
    报文不能同时包含Content-Length头域和非"identity" Transfer-Encoding.如果出现? Content-Length域必被忽略.
    当Content-Length域在允许报文体的报文中存在时, 其域值必M格等于消息体中的8比特字节.HTTP/1.1 user agent 必须在接收ƈ到一个错误的长度时提醒用?
    以上Ҏ中,最常见的还是用Content-Length域表C报文体长度QTransfer-Encoding需要按格式解码才能q原出发送编码前的报文?br />

    支持持久q接的客L可以水发送请求,服务端必L发送的序发送应{?br />     假定持久q接和连接后卛_水的客L应当做好在第一ơ流水失败后重新试此连接。在q样的尝试中Q在定q接是持久的之前Q客L不能再流水?br />     客户端同样必d备好在服务端送回所有相兛_{前关闭连接时重发h?br />     不应水non-idempotentҎ

Proxy Servers
    对于代理服务端而言Q正实现Connection头域指定的属性尤为重要?br />     代理服务端必d立通告它的客户端和q接的原始服务端持久q接的属性,每个持久q接讄仅针对一个传输连接?br />    
实践考量
    时|服务端通常会ؓ每个q接l护一个定时器Q一旦某个连接不z跃过一定时间|服务端会关闭此连接。考虑C个客L可能通过代理服务端发出更多连接,代理服务端通常会将时D|得更高?br />     q有一些关于从异步关闭中恢复的讨论?br />
报文传输要求
    使用TCP控制来解决服务端时负载过高问题,而不是简单的依赖客户端重q而关闭连接?br />     监视q接情况以获取错误状态消?br />     关于使用100(l箋)状态码
    100状态码用于客户端发送请求体之前试是否可以发送该hQ对于ProxyQ有以下要求Q?br /> 1.如果代理服务端接收到包含Expect头域gؓ"100-continue"的请? 而不明确知道下一x务不支持HTTP/1.1以上版本, 则它必须转发q个h, 包括Expect头域.
2.如果代理知道下一x务端为HTTP/1.0或者更低版? 则它不能转发此请? 且必M407应答客户?
3.如果明确知道发出h的客L版本为HTTP/1.0或者更低,则代理服务端l不能{?00应答,q条规则凌驾于{?xx应答的一般准?

Connection头域说明
BNF文法Q?br />     Connection = "Connection" ":" 1#(connection-token)
    connection-token  = token
   
Connection头域中的token用于指定对于特定q接有意义的选项Q因此proxy在{发前要扫描此域,从头中去除和token同名的域。例如Connection:Range,则要LRange域?br />     HTTP/1.1定义了closeq个tokenQ发送者用此token表示在完成这个报文所属请?应答的收发后q接关闭?br />



LukeW 2008-09-24 18:01 发表评论
]]>
关于断点l传的调?/title><link>http://www.aygfsteel.com/lukewange-hit1983/archive/2008/09/24/230950.html</link><dc:creator>LukeW</dc:creator><author>LukeW</author><pubDate>Wed, 24 Sep 2008 09:57:00 GMT</pubDate><guid>http://www.aygfsteel.com/lukewange-hit1983/archive/2008/09/24/230950.html</guid><wfw:comment>http://www.aygfsteel.com/lukewange-hit1983/comments/230950.html</wfw:comment><comments>http://www.aygfsteel.com/lukewange-hit1983/archive/2008/09/24/230950.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/lukewange-hit1983/comments/commentRss/230950.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/lukewange-hit1983/services/trackbacks/230950.html</trackback:ping><description><![CDATA[一些讨?<br /> http://topic.csdn.net/t/20061214/22/5231907.html <img src ="http://www.aygfsteel.com/lukewange-hit1983/aggbug/230950.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/lukewange-hit1983/" target="_blank">LukeW</a> 2008-09-24 17:57 <a href="http://www.aygfsteel.com/lukewange-hit1983/archive/2008/09/24/230950.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <a href="http://www.aygfsteel.com/" title="狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频">狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频</a> </div> </footer> վ֩ģ壺 <a href="http://" target="_blank">̨ʡ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Ǭ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Ԫı</a>| <a href="http://" target="_blank">ˮ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ӳ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ͭ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Ļ</a>| <a href="http://" target="_blank">ƶ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ӽ</a>| <a href="http://" target="_blank">³</a>| <a href="http://" target="_blank">ˮ</a>| <a href="http://" target="_blank">㺺</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ǿ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ƾ</a>| <a href="http://" target="_blank">ɳ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">»</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Ϳ</a>| <a href="http://" target="_blank">ʲ</a>| <a href="http://" target="_blank">÷</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">˫</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Ͱ</a>| <a href="http://" target="_blank">Ȫ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>